New upstream version 7.4.3+git20180601
Willi Mann
5 years ago
336 | 336 | Finally, if the directory /usr/share/logwatch/scripts/logfiles/<logfile_group_name>/ |
337 | 337 | exists, any scripts in that directory will be executed. All of these |
338 | 338 | scripts take the contents of all the specified logfiles in through STDIN and |
339 | output the modified logfile trought STDOUT. | |
339 | output the modified logfile through STDOUT. | |
340 | 340 | |
341 | 341 | |
342 | 342 | B. Service Filter Configuration File |
457 | 457 | use the detail setting: |
458 | 458 | |
459 | 459 | 0 (Low): Display only errors and security-related issues |
460 | 5 (Med): Display anything that a typical administator would be interested in | |
460 | 5 (Med): Display anything that a typical administrator would be interested in | |
461 | 461 | 10 (High): Display anything that a paranoid administrator would want to see |
462 | 462 | |
463 | 463 | In some cases, you can use a security setting higher than 10. This would be |
472 | 472 | *SharedScriptCommand [= Arguments] |
473 | 473 | |
474 | 474 | Logwatch will search for the command in /usr/share/logwatch/scripts/shared/ and |
475 | /etc/logwatch/scripts/shared/. The command name is case insensitiv and can be | |
476 | used in logfile and service group configuratin files. Everything after the | |
475 | /etc/logwatch/scripts/shared/. The command name is case insensitive and can be | |
476 | used in logfile and service group configuration files. Everything after the | |
477 | 477 | equal sign will be passed as arguments to the command. |
478 | 478 | The following shared scripts are shipped with logwatch (they don't accept any |
479 | 479 | arguments unless otherwise mentioned): |
44 | 44 | mkdir /var/cache/logwatch |
45 | 45 | ln -s /usr/share/logwatch/scripts/logwatch.pl /etc/cron.daily/0logwatch |
46 | 46 | ln -s /usr/share/logwatch/scripts/logwatch.pl /usr/sbin/logwatch |
47 | ||
48 | Instead of cron you may also use systemd timer unit for scheduled runs: | |
49 | mv logwatch.service /etc/systemd/system | |
50 | mv logwatch.timer /etc/systemd/system | |
51 | systemd enable logwatch.timer | |
47 | 52 | |
48 | 53 | This is only a suggestion and if you look at the logwatch.pl script and the |
49 | 54 | logwatch.conf file you will see that you can configure the system layout in many |
102 | 102 | The next (optional) summary grouping shows message disposition by contents category. |
103 | 103 | There were 18 malware messages and 4 banned file messages (all blocked), |
104 | 104 | 1168 Spam messages, of which 416 were blocked (quarantined) and 752 discarded. |
105 | Finally, there were 19123 messages consdidered to be Ham (i.e. not spam), 47 | |
105 | Finally, there were 19123 messages considered to be Ham (i.e. not spam), 47 | |
106 | 106 | of which contained bad headers. |
107 | 107 | |
108 | 108 | Additional count summaries for a variety of events are also listed. |
444 | 444 | Additional code modules Amavis loaded during runtime. |
445 | 445 | |
446 | 446 | .IP "\fBFakeSender" |
447 | Forged sender addresses, as determimed by Amavis. | |
447 | Forged sender addresses, as determined by Amavis. | |
448 | 448 | |
449 | 449 | .IP "\fBFatal" |
450 | 450 | Fatal events. These are presented at the top of the report, as they may require attention. |
0 | # What actual file? Defaults to LogPath if not absolute path.... | |
1 | LogFile = dnf.rpm.log | |
2 | ||
3 | Archive = dnf.rpm.log-* | |
4 | ||
5 | # Keep only the lines in the proper date range... | |
6 | *ApplyStdDate = "%b %d %H:%M:%S" | |
7 | ||
8 | # vi: shiftwidth=3 tabstop=3 et |
39 | 39 | # These scripts were created as part of the dnssec-tools project. |
40 | 40 | # For more information, see http://sourceforge.net/dnssec-tools. |
41 | 41 | # Detailed instructions for setting up BIND 9.3.* to use these logwatch |
42 | # configuration files and scripts are containted in the README file | |
42 | # configuration files and scripts are contained in the README file | |
43 | 43 | # on sourceforge. |
44 | 44 | ############################################################################# |
45 | 45 |
9 | 9 | # Jeremias Reith <jr@terragate.net> |
10 | 10 | # |
11 | 11 | # Please send all comments, suggestions, bug reports, |
12 | # etc, to jr@terragate.net and logwatch-devel@logatch.org | |
12 | # etc, to jr@terragate.net and logwatch-devel@logwatch.org | |
13 | 13 | # |
14 | 14 | ############################################################################### |
15 | 15 |
39 | 39 | # These scripts were created as part of the dnssec-tools project. |
40 | 40 | # For more information, see http://sourceforge.net/dnssec-tools. |
41 | 41 | # Detailed instructions for setting up BIND 9.3.* to use these logwatch |
42 | # configuration files and scripts are containted in the README file | |
42 | # configuration files and scripts are contained in the README file | |
43 | 43 | # on sourceforge. |
44 | 44 | ############################################################################# |
45 | 45 |
36 | 36 | Format = text |
37 | 37 | #To make Base64 [aka uuencode] Encode = base64 |
38 | 38 | Encode = none |
39 | ||
40 | # Input Encoding | |
41 | # Logwatch assumes that the input is in UTF-8 encoding. Defining CharEncoding | |
42 | # will use iconv to convert text to the UTF-8 encoding. Set CharEncoding | |
43 | # to an empty string to use the default current locale. If set to a valid | |
44 | # encoding, the input characters are converted to UTF-8, discarding any | |
45 | # illegal characters. Valid encodings are as used by the iconv program, | |
46 | # and `iconv -l` lists valid character set encodings. | |
47 | # Setting CharEncoding to UTF-8 simply discards illegal UTF-8 characters. | |
48 | #CharEncoding = "" | |
39 | 49 | |
40 | 50 | # Default person to mail reports to. Can be a local account or a |
41 | 51 | # complete email address. Variable Output should be set to mail, or |
113 | 123 | mailer = "/usr/sbin/sendmail -t" |
114 | 124 | |
115 | 125 | # |
116 | # With this option set to a comma separted list of hostnames, only log entries | |
126 | # With this option set to a comma separated list of hostnames, only log entries | |
117 | 127 | # for these particular hosts will be processed. This can allow a log host to |
118 | 128 | # process only its own logs, or Logwatch can be run once per a set of hosts |
119 | 129 | # included in the logfiles. |
125 | 135 | # |
126 | 136 | #HostLimit = myhost |
127 | 137 | |
138 | # | |
139 | # By default /var/adm is searched after LogDir. | |
140 | #AppendVarAdmToLogDirs = 1 | |
141 | ||
142 | # | |
143 | # By default /var/log is to be searched after LogDir and /var/adm/ . | |
144 | #AppendVarLogToLogDirs = 1 | |
145 | ||
146 | # | |
147 | # By default the current working directory is searched last after LogDir, /var/adm/, and /var/log/ . | |
148 | #AppendCWDToLogDirs = 1 | |
149 | ||
128 | 150 | # vi: shiftwidth=3 tabstop=3 et |
56 | 56 | $amavis_Show_Sect_Vars = No |
57 | 57 | |
58 | 58 | # In reports, for tallying purposes, use (and show) only the first |
59 | # recipient when a message contains multple recipients. | |
59 | # recipient when a message contains multiple recipients. | |
60 | 60 | # |
61 | 61 | $amavis_Show_First_Recip_Only = No |
62 | 62 |
0 | Title = "dnf-rpm" | |
1 | ||
2 | # Which logfile group... | |
3 | LogFile = dnf-rpm | |
4 | ||
5 | # vi: shiftwidth=3 tabstop=3 et |
39 | 39 | # These scripts were created as part of the dnssec-tools project. |
40 | 40 | # For more information, see http://sourceforge.net/dnssec-tools. |
41 | 41 | # Detailed instructions for setting up BIND 9.3.* to use these logwatch |
42 | # configuration files and scripts are containted in the README file | |
42 | # configuration files and scripts are contained in the README file | |
43 | 43 | # on sourceforge. |
44 | 44 | ############################################################################# |
45 | 45 |
19 | 19 | ######################################################### |
20 | 20 | ## LVM Threshold values. |
21 | 21 | ## These allow you to configure the output and restrict verbose reports |
22 | ## by limiting what is printed to occurances >= the value you enter. | |
22 | ## by limiting what is printed to occurrences >= the value you enter. | |
23 | 23 | ## |
24 | 24 | ## Note that case is insensitive. |
25 | 25 | # |
39 | 39 | # These scripts were created as part of the dnssec-tools project. |
40 | 40 | # For more information, see http://sourceforge.net/dnssec-tools. |
41 | 41 | # Detailed instructions for setting up BIND 9.3.* to use these logwatch |
42 | # configuration files and scripts are containted in the README file | |
42 | # configuration files and scripts are contained in the README file | |
43 | 43 | # on sourceforge. |
44 | 44 | ############################################################################# |
45 | 45 |
2 | 2 | ########################################################################### |
3 | 3 | |
4 | 4 | Title = "rsyslogd" |
5 | LogFile = | |
6 | 5 | LogFile = syslog |
6 | LogFile = messages | |
7 | 7 | *OnlyService = rsyslogd |
8 | 8 | *RemoveHeaders |
9 | 9 | |
10 | # If you want to ignore messagges about certain actions or modules, list | |
11 | # them here, separated by ;'s. | |
12 | # For example, machines with intermittent network connectivity might | |
13 | # want to ignroe issues with forwarded messages. | |
14 | # rsyslogd_ignore_action = action 0 | |
15 | # rsyslogd_ignore_modules = buildtin:omfwd | |
16 | ||
17 | # If you want to ignore specific messagges, list them here separated by ;'s. | |
18 | # rsyslogd_ignore_messages = unexpected GnuTLS error -53 - this could be caused by a broken connection. GnuTLS reports: Error in the push function. | |
19 | ||
10 | 20 | # vi: shiftwidth=3 tabstop=3 et |
127 | 127 | ######################################################### |
128 | 128 | # Sendmail Threshold values. |
129 | 129 | # These allow you to configure the output and restrict verbose reports |
130 | # by limiting what is printed to occurances >= the value you enter. | |
130 | # by limiting what is printed to occurrences >= the value you enter. | |
131 | 131 | # |
132 | 132 | # Note that case is insensitive. |
133 | 133 |
12 | 12 | # Which logfile group... |
13 | 13 | LogFile = messages |
14 | 14 | |
15 | # Only give lines pertaining to the sssd service... | |
16 | *OnlyService = sssd | |
17 | *RemoveHeaders | |
15 | # OnlyService doesn't work with sssd services | |
16 | *RemoveHeaders = "^... .. ..:..:.. [^ ]* " | |
18 | 17 | |
19 | 18 | # vi: shiftwidth=3 tabstop=3 et |
16 | 16 | *OnlyService = systemd |
17 | 17 | *RemoveHeaders |
18 | 18 | |
19 | # Ignore unit failed messages | |
20 | # The value is a regular expression that the unit name is matched | |
21 | # against. Separate multiple units with | | |
22 | # $ignore_failed = ntpdate.service | |
23 | ||
19 | 24 | # vi: shiftwidth=3 tabstop=3 et |
20 | 20 | *OnlyService = vpopmail |
21 | 21 | *RemoveHeaders = |
22 | 22 | |
23 | # Do you want to report succeful logins? | |
23 | # Do you want to report successful logins? | |
24 | 24 | $successful_logins = 0 |
25 | 25 | |
26 | 26 | # vi: shiftwidth=3 tabstop=3 et |
19 | 19 | # Set this to 1 if you want to ignore unmatched FTP messages... |
20 | 20 | $vsftpd_ignore_unmatched = 0 |
21 | 21 | |
22 | # Set this to 1 if you want to ignore requests for robots.txt | |
23 | $vsftpd_ignore_robots = 0 | |
24 | ||
22 | 25 | # NOTE: Be sure to add these to your FTP server's vsftpd.conf file: |
23 | 26 | # (NOT this logwatch configuration file) |
24 | 27 | # xferlog_enable=YES |
41 | 41 | #$diskfull_threshold = 0 |
42 | 42 | |
43 | 43 | # Regular expression to exclude directories from disk full warnings. |
44 | # Expression is achored at the beginning with ^, but not at the end. | |
44 | # Expression is anchored at the beginning with ^, but not at the end. | |
45 | 45 | #$diskfull_exclude_dirs = /run/media |
46 | 46 | |
47 | 47 | ######################################################## |
78 | 78 | MANDIR="/usr/share/man" |
79 | 79 | |
80 | 80 | #Command line options section |
81 | #Currently only prefix is supported but now that the door is open other options should follow. -mgt | |
82 | 81 | ac_prev= |
82 | systemd=0 | |
83 | 83 | for ac_option |
84 | 84 | do |
85 | 85 | # If the previous option needs an argument, assign it. |
96 | 96 | ac_prev=prefix ;; |
97 | 97 | -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) |
98 | 98 | prefix=$ac_optarg ;; |
99 | --systemd) | |
100 | systemd=1;; | |
99 | 101 | *) |
100 | 102 | echo "Unknown option '$ac_option'" |
103 | echo "Valid options are --prefix and --systemd." | |
104 | echo " Option --prefix takes one argument: a path name, which will" | |
105 | echo " be prepended to installation directory names" | |
106 | echo " Option --systemd installs the systemd files logwatch.service" | |
107 | echo " and logwatch.timer rather than the default 0logwatch" | |
108 | echo " file in /etc/cron.daily/" | |
109 | exit | |
101 | 110 | ;; |
102 | 111 | esac |
103 | 112 | done |
233 | 242 | |
234 | 243 | #TEMP |
235 | 244 | #Using sanity check incase someone uses /tmp. |
236 | #The install would destory the perms on /tmp | |
245 | #The install would destroy the perms on /tmp | |
237 | 246 | if [ ! -d $TEMPDIR ]; then |
238 | 247 | #Should this be 0700 -d $TEMPDIR ?? |
239 | 248 | install -m 0755 -d $TEMPDIR |
319 | 328 | ln -f -s $BASEDIR/scripts/logwatch.pl /usr/sbin/logwatch |
320 | 329 | printf "Created symlink for /usr/sbin/logwatch \n" |
321 | 330 | |
322 | #Cron | |
323 | if [ -d /etc/cron.daily ]; then | |
331 | #Cron or Systemd timer | |
332 | if [ $systemd -eq 1 ]; then | |
333 | install -m 0644 scheduler/logwatch.service /lib/systemd/system/logwatch.service | |
334 | install -m 0644 scheduler/logwatch.timer /lib/systemd/system/logwatch.timer | |
335 | if [ ! -e /lib/systemd/system/multi-user.target.wants ]; then | |
336 | install -m 0755 -d /lib/systemd/system/multi-user.target.wants | |
337 | fi | |
338 | ln -s ../logwatch.timer /lib/systemd/system/multi-user.target.wants/logwatch.timer | |
339 | printf "Created and enabled systemd logwatch.timer" | |
340 | elif [ -d /etc/cron.daily ]; then | |
324 | 341 | rm -f /etc/cron.daily/0logwatch |
325 | install -m 0755 logwatch.cron /etc/cron.daily/0logwatch | |
342 | install -m 0755 scheduler/logwatch.cron /etc/cron.daily/0logwatch | |
326 | 343 | printf "Created /etc/cron.daily/0logwatch \n" |
327 | 344 | else |
328 | install -m 0744 logwatch.cron $CONFIGDIR/logwatch.cron | |
345 | install -m 0744 scheduler/logwatch.cron $CONFIGDIR/logwatch.cron | |
329 | 346 | printf "################ README ####################.\n" |
330 | 347 | printf "You need to setup your cron job for logwatch.\n" |
331 | 348 | printf "A sample script is included see $CONFIGDIR/logwatch.cron. \n" |
283 | 283 | |
284 | 284 | # for 99% of the uses of this function, assuming package 'main' would |
285 | 285 | # be sufficient, but a good perl hacker designs so that the other 1% |
286 | # isn't in for a nasty suprise. | |
286 | # isn't in for a nasty surprise. | |
287 | 287 | my $pkg = (caller)[0]; |
288 | 288 | |
289 | 289 | if ($ENV{'LOGWATCH_NUMERIC'} == 1 ) |
408 | 408 | (The last entry might be used by someone debugging a log or filter.) |
409 | 409 | |
410 | 410 | A caution about efficiency: a range of \"yesterday for those hours\" |
411 | will search for log entries for the last 24 hours, and is innefficient | |
411 | will search for log entries for the last 24 hours, and is inefficient | |
412 | 412 | because it searches for individual matches for each hour. A range of |
413 | 413 | \"yesterday\" will search for log entries for the previous day, and |
414 | 414 | it searches for a single date match. |
108 | 108 | then only logs from this hostname will be processed (where appropriate). |
109 | 109 | .IP "\fB--html_wrap\fR num-characters" |
110 | 110 | Number of characters that html output should be wrapped to. Default is 80. |
111 | .IP "\fB--hostformat\fR split" | |
112 | Use | |
113 | .I split | |
114 | approach when formatting report for multiple hosts - none [default], split, splitmail. | |
115 | .IP "\fB--output\fR output-type" | |
116 | Report using | |
117 | .I output-type | |
118 | - stdout [default], mail, file. | |
119 | .IP "\fB--format\fR format" | |
120 | Format report using | |
121 | .I format | |
122 | - text [default], html. | |
123 | .IP "\fB--encode\fR encoding" | |
124 | Encode report using | |
125 | .I encoding | |
126 | - none [default], base64. | |
111 | 127 | .IP "\fB--numeric\fR" |
112 | 128 | Inhibits additional name lookups, displaying IP addresses numerically. |
113 | 129 | .IP "\fB--usage\fR" |
16 | 16 | .BR /etc/logwatch/conf/ignore.conf |
17 | 17 | ) |
18 | 18 | is the list of regular expressions. |
19 | The set of logs decribed by this set is ignored by logwatch. | |
19 | The set of logs described by this set is ignored by logwatch. | |
20 | 20 | |
21 | 21 | .BR override.conf |
22 | 22 | - ( |
0 | #!/bin/sh | |
1 | ||
2 | #Set logwatch location | |
3 | LOGWATCH_SCRIPT="/usr/sbin/logwatch" | |
4 | #Add options to this line. Most options should be defined in /etc/logwatch/conf/logwatch.conf, | |
5 | #but some are only for the nightly cronrun such as --output mail and should be set here. | |
6 | #Other options to consider might be "--format html" or "--encode base64", man logwatch for more details. | |
7 | OPTIONS="--output mail" | |
8 | ||
9 | #Call logwatch | |
10 | $LOGWATCH_SCRIPT $OPTIONS | |
11 | ||
12 | exit 0 |
192 | 192 | .IP "\fB--[no]summary\fR" |
193 | 193 | .IP "\fB--show_summary\fR" |
194 | 194 | Enables (disables) displaying of the the \fBSummary\fR section of the report. |
195 | The variable Posfix_Show_Summary in used in a configuration file. | |
195 | The variable postfix_Show_Summary in used in a configuration file. | |
196 | 196 | .IP "\fB--recipient_delimiter \fIdelimiter\fR" |
197 | 197 | Split email delivery addresses using the recipient delimiter character \fIdelimiter\fR. |
198 | 198 | This should generally match |
200 | 200 | file \fBmain.cf\fR, or the default value indicated in |
201 | 201 | \fBpostconf -d recipient_delimiter\fR. |
202 | 202 | This is very useful for obtaining per-alias statistics |
203 | when a recipient delimeter is used for mail delivery. | |
203 | when a recipient delimiter is used for mail delivery. | |
204 | 204 | .IP "\fB--reject_reply_patterns \fIr1 [r2 ...]\fR" |
205 | 205 | Specifies the list of reject reply patterns used to create reject groups. |
206 | 206 | Each entry in the list \fIr1 [r2 ...]\fR must be either a three character |
339 | 339 | .IP "\fBDiscarded" |
340 | 340 | Messages that triggered access, header_checks or body_checks DISCARD action. |
341 | 341 | .IP "\fBDNSError" |
342 | Any one of several errors encounted during DNS lookups. | |
342 | Any one of several errors encountered during DNS lookups. | |
343 | 343 | .IP "\fBEnvelopeSenderDomains" |
344 | 344 | List of sending domains. (2 levels: envelope sender domain, localpart) |
345 | 345 | .IP "\fBEnvelopeSenders" |
471 | 471 | .IP "\fBTlsClientConnect" |
472 | 472 | TLS client connections. |
473 | 473 | .IP "\fBTlsOffered" |
474 | TLS communication offerred. | |
474 | TLS communication offered. | |
475 | 475 | .IP "\fBTlsServerConnect" |
476 | 476 | TLS server connections. |
477 | 477 | .IP "\fBTlsUnverified" |
0 | #!/bin/sh | |
1 | ||
2 | #Set logwatch location | |
3 | LOGWATCH_SCRIPT="/usr/sbin/logwatch" | |
4 | #Add options to this line. Most options should be defined in /etc/logwatch/conf/logwatch.conf, | |
5 | #but some are only for the nightly cronrun such as --output mail and should be set here. | |
6 | #Other options to consider might be "--format html" or "--encode base64", man logwatch for more details. | |
7 | OPTIONS="--output mail" | |
8 | ||
9 | #Call logwatch | |
10 | $LOGWATCH_SCRIPT $OPTIONS | |
11 | ||
12 | exit 0 |
0 | [Unit] | |
1 | Description=Daily logwatch run | |
2 | ||
3 | [Timer] | |
4 | OnCalendar=daily | |
5 | AccuracySec=1d | |
6 | Persistent=true | |
7 | ||
8 | [Install] | |
9 | WantedBy=multi-user.target |
86 | 86 | $Config{'pathtocat'} = "cat"; |
87 | 87 | $Config{'pathtozcat'} = "zcat"; |
88 | 88 | $Config{'pathtobzcat'} = "bzcat"; |
89 | $Config{'pathtoxzcat'} = "xzcat"; | |
89 | 90 | $Config{'output'} = "stdout"; #8.0 |
90 | 91 | $Config{'format'} = "text"; #8.0 |
91 | 92 | $Config{'encode'} = "none"; #8.0 |
92 | 93 | $Config{'hostformat'} = "none"; #8.0 |
93 | 94 | $Config{'html_wrap'} = 80; |
94 | $Config{'supress_ignores'} = 0; | |
95 | $Config{'suppress_ignores'} = 0; | |
95 | 96 | $Config{'hostlimit'} = ""; |
97 | $Config{'appendvaradmtologdirs'} = 1; | |
98 | $Config{'appendvarlogtologdirs'} = 1; | |
99 | $Config{'appendcwdtologdirs'} = 1; | |
96 | 100 | |
97 | 101 | if (-e "$ConfigDir/conf/html/header.html") { |
98 | 102 | $Config{'html_header'} = "$ConfigDir/conf/html/header.html"; |
143 | 147 | # For each of the configuration sets (logwatch.conf here, and |
144 | 148 | # logfiles,and services later), we do the following: |
145 | 149 | # 1. read the different configuration files |
146 | # 2. for each parameter, if it is cummulative, check if | |
150 | # 2. for each parameter, if it is cumulative, check if | |
147 | 151 | # it the special case empty string |
148 | 152 | # 3. check to see if duplicate |
149 | 153 | |
173 | 177 | $Config{$ReadConfigNames[$i]} = $ReadConfigValues[$i]; |
174 | 178 | } |
175 | 179 | } |
180 | ||
181 | my @LogDirs=("$Config{'logdir'}/"); | |
182 | push @LogDirs, "/var/adm/" if $Config{'appendvaradmtologdirs'}; | |
183 | push @LogDirs, "/var/log/" if $Config{'appendvarlogtologdirs'}; | |
184 | push @LogDirs, "" if $Config{'appendcwdtologdirs'}; | |
176 | 185 | |
177 | 186 | &CleanVars(); |
178 | 187 | |
433 | 442 | @{$LogFileData{$ThisLogFile}{'logfiles'}} = (); |
434 | 443 | } else { |
435 | 444 | if ($ReadConfigValues[$i] !~ m=^/=) { |
436 | foreach my $dir ("$Config{'logdir'}/", "/var/adm/", "/var/log/", "") { | |
445 | foreach my $dir (@LogDirs) { | |
437 | 446 | # We glob to obtain filenames. We reverse in case |
438 | 447 | # we use the decimal suffix (.0, .1, etc.) in filenames |
439 | 448 | #@TempLogFileList = reverse(glob($dir . $ReadConfigValues[$i])); |
472 | 481 | @{$LogFileData{$ThisLogFile}{'archives'}} = (); |
473 | 482 | } else { |
474 | 483 | if ($ReadConfigValues[$i] !~ m=^/=) { |
475 | foreach my $dir ("$Config{'logdir'}/", "/var/adm/", "/var/log/", "") { | |
484 | foreach my $dir (@LogDirs) { | |
476 | 485 | # We glob to obtain filenames. We reverse in case |
477 | 486 | # we use the decimal suffix (.0, .1, etc.) in filenames |
478 | 487 | #@TempLogFileList = reverse(glob($dir . $ReadConfigValues[$i])); |
725 | 734 | } |
726 | 735 | |
727 | 736 | @FileList = $TempDir . $LogFile . "-archive"; |
728 | push @FileList, @{$LogFileData{$LogFile}{'logfiles'}}; | |
737 | ||
738 | # Handle compressed log files using the archive codepath | |
739 | foreach my $lf (@{$LogFileData{$LogFile}{'logfiles'}}) { | |
740 | if ($lf =~ /\.(?:gz|bz2|xz)$/) { | |
741 | push @{$LogFileData{$LogFile}{'archives'}}, $lf; | |
742 | } else { | |
743 | push @FileList, $lf; | |
744 | } | |
745 | } | |
746 | ||
729 | 747 | my $DestFile = $TempDir . $LogFile . "-archive"; |
730 | 748 | my $Archive; |
731 | 749 | foreach $Archive (@{$LogFileData{$LogFile}{'archives'}}) { |
767 | 785 | my $arguments = "'${Archive}' 2>/dev/null >> $DestFile"; |
768 | 786 | system("$Config{'pathtobzcat'} $arguments") == 0 |
769 | 787 | or die "system '$Config{'pathtobzcat'} $arguments' failed: $?" |
788 | } elsif (($Archive =~ m/xz$/) && (-f "$Archive") && (-s "$Archive")) { | |
789 | my $arguments = "'${Archive}' 2>/dev/null >> $DestFile"; | |
790 | system("$Config{'pathtoxzcat'} $arguments") == 0 | |
791 | or die "system '$Config{'pathtoxzcat'} $arguments' failed: $?" | |
770 | 792 | } elsif ((-f "$Archive") && (-s "$Archive")) { |
771 | 793 | my $arguments = "'${Archive}' >> $DestFile"; |
772 | 794 | system("$Config{'pathtocat'} $arguments") == 0 |
803 | 825 | @EnvList = (); |
804 | 826 | |
805 | 827 | my $FilterText = " "; |
828 | if (-e "/usr/bin/iconv") { | |
829 | if (defined $Config{'charencoding'}) { | |
830 | my $from_encoding; | |
831 | if ($Config{'charencoding'}) { | |
832 | $from_encoding = "-f $Config{'charencoding'}"; | |
833 | } else { | |
834 | $from_encoding = ""; | |
835 | } | |
836 | $FilterText = " | iconv -c $from_encoding -t UTF-8 - "; | |
837 | } | |
838 | } | |
806 | 839 | foreach (sort keys %{$LogFileData{$LogFile}}) { |
807 | 840 | my $cmd = $_; |
808 | 841 | if ($cmd =~ s/^\d+-\*//) { |
1080 | 1113 | sub Usage () { |
1081 | 1114 | # Show usage for this program |
1082 | 1115 | print "\nUsage: $0 [--detail <level>] [--logfile <name>] [--output <output_type>]\n" . |
1083 | " [--format <format_type>] [--encode <enconding>] [--numeric]\n" . | |
1116 | " [--format <format_type>] [--encode <encoding>] [--numeric]\n" . | |
1084 | 1117 | " [--mailto <addr>] [--archives] [--range <range>] [--debug <level>]\n" . |
1085 | 1118 | " [--filename <filename>] [--help|--usage] [--version] [--service <name>]\n" . |
1086 | 1119 | " [--hostformat <host_format type>] [--hostlimit <host1,host2>] [--html_wrap <num_characters>]\n\n"; |
1090 | 1123 | print "--service <name>: *Name of a service definition to report on.\n"; |
1091 | 1124 | print "--output <output type>: Report Output - stdout [default], mail, file.\n"; #8.0 |
1092 | 1125 | print "--format <formatting>: Report Format - text [default], html.\n"; #8.0 |
1093 | print "--encode <encoding>: Enconding to use - none [default], base64.\n"; #8.0 | |
1126 | print "--encode <encoding>: Encoding to use - none [default], base64.\n"; #8.0 | |
1094 | 1127 | print "--mailto <addr>: Mail report to <addr>.\n"; |
1095 | 1128 | print "--archives: Use archived log files too.\n"; |
1096 | 1129 | print "--filename <filename>: Used to specify they filename to save to. --filename <filename> [Forces output to file].\n"; |
1399 | 1432 | |
1400 | 1433 | if ($has_output and $ServiceData{$Service}{'title'}) { |
1401 | 1434 | if ( $Config{'format'} eq "html" ) { |
1402 | if ( ($Ignored > 0) && ($Config{'supress_ignores'} == 0) ) { &output( $index_par, "\n $Ignored Ignored Lines\n", "header"); }; | |
1435 | if ( ($Ignored > 0) && ($Config{'suppress_ignores'} == 0) ) { &output( $index_par, "\n $Ignored Ignored Lines\n", "header"); }; | |
1403 | 1436 | #&output( $index_par, "\n <h3><font color=\"blue\">$ServiceData{$Service}{'title'} End </font></h3>\n", "header"); |
1404 | 1437 | } else { |
1405 | if ( ($Ignored > 0) && ($Config{'supress_ignores'} == 0) ) { &output( $index_par, "\n $Ignored Ignored Lines\n", "line"); }; | |
1438 | if ( ($Ignored > 0) && ($Config{'suppress_ignores'} == 0) ) { &output( $index_par, "\n $Ignored Ignored Lines\n", "line"); }; | |
1406 | 1439 | &output( $index_par, "\n ---------------------- $ServiceData{$Service}{'title'} End ------------------------- \n\n", "line"); |
1407 | 1440 | } |
1408 | 1441 | &output( $index_par, "\n", "stop"); |
1460 | 1493 | if (defined fileno OUTFILE) { |
1461 | 1494 | print OUTFILE $out_mime if $out_mime; |
1462 | 1495 | if ( $Config{'encode'} eq "base64" ) { |
1463 | print OUTFILE encode_base64($out_head) if $out_head; | |
1464 | print OUTFILE encode_base64($out_reference) if $out_reference; | |
1496 | my $out = ''; | |
1497 | $out .= $out_head if $out_head; | |
1498 | $out .= $out_reference if $out_reference; | |
1465 | 1499 | foreach ( 0 .. $index_par ) { |
1466 | print OUTFILE encode_base64($out_body{$_}) if defined( $out_body{$_} ); | |
1467 | #fixme | |
1500 | $out .= $out_body{$_} if defined( $out_body{$_} ); | |
1468 | 1501 | $out_body{$_} = ''; #We should track this down out_body could be an array instead also -mgt |
1469 | 1502 | } |
1470 | print OUTFILE encode_base64($out_foot) if $out_foot; | |
1503 | $out .= $out_foot if $out_foot; | |
1504 | print OUTFILE encode_base64($out); | |
1471 | 1505 | } else { |
1472 | 1506 | print OUTFILE $out_head if $out_head; |
1473 | 1507 | print OUTFILE $out_reference if $out_reference; |
54 | 54 | ) { |
55 | 55 | # We don't care about these |
56 | 56 | } |
57 | elsif ( my ($Junk,$Login) = ( $ThisLine =~ /(login|Login by) ([^ ]+)$/) ) { | |
57 | elsif ( my ($Junk,$Login) = ( $ThisLine =~ /(login|Login by) ([^ ]+)/) ) { | |
58 | 58 | chomp($Login); |
59 | 59 | $UserLogin{$Login}++; |
60 | 60 | } |
618 | 618 | my $pass_through = shift; |
619 | 619 | #$SIG{__WARN__} = sub { print "*** $_[0]*** options error\n" }; |
620 | 620 | # ensure we're called after %Opts is initialized |
621 | die "get_options: program error: %Opts is emtpy" unless exists $Opts{'debug'}; | |
621 | die "get_options: program error: %Opts is empty" unless exists $Opts{'debug'}; | |
622 | 622 | |
623 | 623 | my $p = new Getopt::Long::Parser; |
624 | 624 | |
995 | 995 | |
996 | 996 | a = show level a detail |
997 | 997 | b = show at most b items at this level |
998 | c = minimun count that will be shown | |
998 | c = minimum count that will be shown | |
999 | 999 | =cut |
1000 | 1000 | |
1001 | 1001 | sub printTree($ $ $ $ $) { |
1096 | 1096 | # TOTAL: an integer: which is the subtotal of this item's children |
1097 | 1097 | # LEVEL: an integer > 0: representing this entry's level in the tree |
1098 | 1098 | # CHILDREF: a listref: references a list consisting of this node's children |
1099 | # Total: The cummulative total of items found for a given invocation | |
1099 | # Total: The cumulative total of items found for a given invocation | |
1100 | 1100 | # |
1101 | 1101 | # Use the special key variable $END_KEY, which is "\a\a" (two ASCII bell's) to end a, |
1102 | 1102 | # nested hash early, or the empty string '' may be used as the last key. |
1333 | 1333 | $$divisor == $Totals{$keyname} ? 100.00 : $Totals{$keyname} * 100 / $$divisor; |
1334 | 1334 | } |
1335 | 1335 | else { |
1336 | push @{$lines[$cur_level]}, | |
1337 | sprintf "$fmt %-23s $extra\n", $total, $desc, commify ($Totals{$keyname}); | |
1336 | my $out = sprintf "$fmt %-23s", $total, $desc; | |
1337 | if ($extra) { | |
1338 | $out .= sprintf " $extra", commify ($Totals{$keyname}); | |
1339 | } | |
1340 | $out .= "\n"; | |
1341 | push @{$lines[$cur_level]}, $out; | |
1338 | 1342 | } |
1339 | 1343 | } |
1340 | 1344 | } |
1735 | 1739 | my @ignore_list_final = (); |
1736 | 1740 | |
1737 | 1741 | # The Sections table drives Summary and Detail reports. For each entry in the |
1738 | # table, if there is data avaialable, a line will be output in the Summary report. | |
1742 | # table, if there is data available, a line will be output in the Summary report. | |
1739 | 1743 | # Additionally, a sub-section will be output in the Detail report if both the |
1740 | 1744 | # global --detail, and the section's limiter variable, are sufficiently high (a |
1741 | 1745 | # non-existent section limiter variable is considered to be sufficiently high). |
2686 | 2690 | elsif ($p1 =~ /^mangling (.*)$/) { |
2687 | 2691 | $p1 = $1; |
2688 | 2692 | if ($p1 =~ /^by (.+?) failed: (.+?), mail will pass unmodified$/) { |
2689 | #TD mangling by altermine failed: SomeText, mail will pass unmodified | |
2693 | #TD mangling by altermime failed: SomeText, mail will pass unmodified | |
2690 | 2694 | $Totals{'defangerror'}++; next unless ($Collecting{'defangerror'}); |
2691 | 2695 | $Counts{'defangerror'}{$1}{$2}++; |
2692 | 2696 | } |
3344 | 3348 | qw(totalmalware totalbanned totalunchecked totalspam totalham totalother)); |
3345 | 3349 | |
3346 | 3350 | # Print the summary report if any key has non-zero data. |
3347 | # Note: must explicitely check for any non-zero data, | |
3351 | # Note: must explicitly check for any non-zero data, | |
3348 | 3352 | # as Totals always has some keys extant. |
3349 | 3353 | # |
3350 | 3354 | if ($Opts{'summary'}) { |
3676 | 3680 | map {$time_total_actual += $_} @$totalsref; |
3677 | 3681 | |
3678 | 3682 | # cutoff value used to limit the number of rows of output |
3679 | # positive cutoff is a percentage of cummulative time | |
3683 | # positive cutoff is a percentage of cumulative time | |
3680 | 3684 | # negative cutoff limits number of rows |
3681 | 3685 | if ($cutoff >= 0) { |
3682 | 3686 | $max_pcnt = $cutoff != 100 ? $cutoff : 150; # 150% avoids roundoff errors |
3988 | 3992 | # 5 to 9 nostartinfo, timings=95, sarules = 20 20, score_frequencies=defaults, score_percentiles=defaults, autolearn |
3989 | 3993 | # 10 + startinfo, timings=100, sarules = all all score_frequencies=defaults, score_percentiles=defaults, autolearn |
3990 | 3994 | |
3991 | if ($Opts{'detail'} < 5) { # detail 0 to 4, disable all supplimental reports | |
3995 | if ($Opts{'detail'} < 5) { # detail 0 to 4, disable all supplemental reports | |
3992 | 3996 | $Opts{'autolearn'} = 0; |
3993 | 3997 | #$Opts{'p0f'} = 0; |
3994 | 3998 | $Opts{'timings'} = 0; |
78 | 78 | use Logwatch ':all'; |
79 | 79 | |
80 | 80 | my (%denials, %grants, %loads); |
81 | my @OtherList; | |
81 | my %OtherList; | |
82 | 82 | my $othercount = 0; |
83 | 83 | my $Debug = ($ENV{'LOGWATCH_DEBUG'} || 0); |
84 | 84 | my $Detail = ($ENV{'LOGWATCH_DETAIL_LEVEL'} || 0); |
115 | 115 | ( $ThisLine =~ /: enforcing=[0-9]+ old_enforcing=[0-9]+ auid=[0-9]+/) or |
116 | 116 | ( $ThisLine =~ /: policy loaded auid=[0-9]+/) or |
117 | 117 | ( $ThisLine =~ /: user pid=[0-9]+ uid=[0-9]+ auid=[0-9]+ subj=system_u:system_r:system_dbusd_t:[0-9a-z:.\-]+ msg=/) or |
118 | ( $ThisLine =~ /audit\([0-9.]+:[0-9]+\): (selinux=[0-9]+|auid=[0-9]+|prom=[0-9]+|old_prom=[0-9]+|dev=[^ ]+|ses=[0-9]+| )+$/) or | |
118 | ( $ThisLine =~ /audit\([0-9.]+:[0-9]+\): (selinux=[0-9]+|auid=[0-9]+|prom=[0-9]+|old_prom=[0-9]+|[ug]id=[0-9]+|dev=[^ ]+|ses=[0-9]+| )+$/) or | |
119 | 119 | ( $ThisLine =~ /auditd[ ]+S [0-9A-F]+ [0-9]+ [0-9]+[ ]+[0-9]([ ]*[0-9]+[ ]*|[ ]*)[0-9]+ [0-9]+ \(NOTLB\)/) or |
120 | 120 | ( $ThisLine =~ /Started dispatcher: \/sbin\/audispd pid: [0-9]+/) or |
121 | ( $ThisLine =~ /dispatcher [0-9]+ reaped/) or | |
121 | 122 | ( $ThisLine =~ /audit\([0-9.]*:[0-9]*\): bool=.* val=.* old_val=.* auid=[0-9]*/) or |
122 | 123 | ( $ThisLine =~ /type=[0-9]+ audit\([0-9.]*:[0-9]*\): audit_enabled=[0-9]* old=[0-9]* auid=[0-9]* ses=[0-9]*/) or |
123 | 124 | ( $ThisLine =~ /type=[0-9]+ audit\([0-9.]*:[0-9]*\): auid=[0-9]* ses=[0-9]* subj=system_u:system_r:.*:s0 op=.* key=.* list=[0-9]* res=[0-9]*/) or |
136 | 137 | ( $ThisLine =~ /^auditctl(?:\[[0-9]+\])?: No rules$/ ) |
137 | 138 | ) { |
138 | 139 | # Ignore these entries |
139 | } elsif ( $ThisLine =~ /audit\([0-9]{10}.[0-9]{3}:[0-9]\): initialized$/) { | |
140 | } elsif ( $ThisLine =~ /audit\([0-9]{10}.[0-9]{3}:[0-9]\): (?:state=)?initialized/) { | |
140 | 141 | $NumberOfInits++; |
141 | 142 | } elsif ( $ThisLine =~ /Init complete, audit pid set to: [0-9]+/) { |
142 | 143 | $NumberOfDStartsPid++; |
179 | 180 | # type=1400 audit(1410503892.382:55490): apparmor="ALLOWED" operation="open" profile="/usr/lib/dovecot/imap" name="/root/mails/.Drafts/dovecot.index.log" pid=6305 comm="imap" requested_mask="rw" denied_mask="rw" fsuid=1003 ouid=1003 |
180 | 181 | $NumberOfAllowedMessages++; |
181 | 182 | } else { |
182 | $othercount++; | |
183 | 183 | $ThisLine =~ s/^\s*//; |
184 | if ($othercount < $UELimit+1) { | |
185 | push @OtherList, $ThisLine; | |
186 | } | |
184 | $OtherList{$ThisLine}++; | |
187 | 185 | } |
188 | 186 | } elsif ( $Detail > 9 ) { |
189 | 187 | if ( $ThisLine =~ /avc:\s*denied\s*{\s*([^}]+).*scontext=(\S+)\s*tcontext=(\S+)\s*tclass=(\S+)/ ) { |
195 | 193 | } elsif ($ThisLine =~ /security_sid_mls_copy:\s*invalid context\s*(\S+)/) { |
196 | 194 | $InvalidContext{"context: ".$1}++; |
197 | 195 | } else { |
198 | $othercount++; | |
199 | 196 | $ThisLine =~ s/^\s*//; |
200 | if ($othercount < $UELimit+1) { | |
201 | push @OtherList, $ThisLine; | |
202 | } | |
197 | $OtherList{$ThisLine}++; | |
203 | 198 | } |
204 | 199 | } elsif ( $Detail > 4 ) { |
205 | 200 | if ( $ThisLine =~ /avc:\s*denied\s*{\s*[^}]+.*scontext=(\S+)\s*tcontext=(\S+)\s*tclass=(\S+)/ ) { |
211 | 206 | } elsif ($ThisLine =~ /security_sid_mls_copy:\s*invalid context\s*(\S+)/) { |
212 | 207 | $InvalidContext{"context: ".$1}++; |
213 | 208 | } else { |
214 | $othercount++; | |
215 | 209 | $ThisLine =~ s/^\s*//; |
216 | if ($othercount < $UELimit+1) { | |
217 | push @OtherList, $ThisLine; | |
218 | } | |
210 | $OtherList{$ThisLine}++; | |
219 | 211 | } |
220 | 212 | } else { |
221 | 213 | if ( $ThisLine =~ /avc:\s*denied\s*{\s*[^}]+.*scontext=([^:]+):[^:]+:\S+\s*tcontext=([^:]+):[^:]+:\S+\s*tclass=(\S+)/ ) { |
227 | 219 | } elsif ($ThisLine =~ /security_sid_mls_copy:\s*invalid context\s*(\S+)/) { |
228 | 220 | $InvalidContext{"context: ".$1}++; |
229 | 221 | } else { |
230 | $othercount++; | |
231 | 222 | $ThisLine =~ s/^\s*//; |
232 | if ($othercount < $UELimit+1) { | |
233 | push @OtherList, $ThisLine; | |
234 | } | |
223 | $OtherList{$ThisLine}++; | |
235 | 224 | } |
236 | 225 | } |
237 | 226 | } |
317 | 306 | } |
318 | 307 | } |
319 | 308 | |
320 | if ( $#OtherList >= 0 ) { | |
321 | print "\n**Unmatched Entries** "; | |
322 | if ($othercount > $UELimit) { | |
323 | print "(Only first $UELimit out of $othercount are printed)"; | |
324 | } | |
325 | print "\n "; | |
326 | print join("\n ", @OtherList); | |
327 | print "\n"; | |
309 | if (keys %OtherList) { | |
310 | print "\n**Unmatched Entries**\n"; | |
311 | foreach my $line (sort {$OtherList{$b}<=>$OtherList{$a} } keys %OtherList) { | |
312 | print " $line: $OtherList{$line} Time(s)\n"; | |
313 | } | |
328 | 314 | } |
329 | 315 | |
330 | 316 | exit(0); |
43 | 43 | } |
44 | 44 | elsif ( ($ThisMount) = ($ThisLine =~ /^attempting to mount entry (.*)$/) ) { |
45 | 45 | # store Mount |
46 | #$Mount = $ThisMount; somthing is wrong with this -mgt | |
46 | #$Mount = $ThisMount; something is wrong with this -mgt | |
47 | 47 | $MountAttempts++; |
48 | 48 | } |
49 | 49 | elsif ($ThisLine =~ /^mount\(nfs\): nfs: mount failure .*:.* on (.*)$/) { |
3 | 3 | # |
4 | 4 | # Barracuda Spam Firewall parser |
5 | 5 | # Written by Hugo van der Kooij <hugo@vanderkooij.org> (HvdK) |
6 | # Based on existing code of logwatch and the docuemntation on: | |
6 | # Based on existing code of logwatch and the documentation on: | |
7 | 7 | # http://www.barracudanetworks.com/ns/downloads/BarracudaSyslog.pdf |
8 | 8 | # |
9 | 9 | # Revision 0.9 2007/08/27 HvdK |
79 | 79 | $Reason[22] = "RCPT TO Syntax Error"; |
80 | 80 | $Reason[23] = "Send EHLO/HELO First"; |
81 | 81 | $Reason[24] = "Need MAIL Command"; |
82 | $Reason[25] = "Nested MAIL Comand"; | |
82 | $Reason[25] = "Nested MAIL Command"; | |
83 | 83 | $Reason[26] = "UNKNOWN (26)"; |
84 | 84 | $Reason[27] = "EHLO/HELO Syntax Error"; |
85 | 85 | $Reason[28] = "UNKNOWN (28)"; |
98 | 98 | $Reason[41] = "Client Host Rejected"; |
99 | 99 | $Reason[42] = "UNKNOWN (42)"; |
100 | 100 | $Reason[43] = "UNKNOWN (43)"; |
101 | $Reason[44] = "Authentication Not Enabed"; | |
101 | $Reason[44] = "Authentication Not Enabled"; | |
102 | 102 | $Reason[45] = "Allowed Message Size Exceeded"; |
103 | 103 | $Reason[46] = "Too Many Recipients"; |
104 | 104 | $Reason[47] = "Need RCPT Command"; |
111 | 111 | $Reason[54] = "UNKNOWN (54)"; |
112 | 112 | $Reason[55] = "Invalid Parameter Syntax"; |
113 | 113 | $Reason[56] = "STARTTLS Syntax Error"; |
114 | $Reason[57] = "TLS Allready Active"; | |
114 | $Reason[57] = "TLS Already Active"; | |
115 | 115 | $Reason[58] = "Too Many Errors"; |
116 | 116 | $Reason[59] = "Need STARTTLS First"; |
117 | 117 | $Reason[60] = "Spam Fingerprint Found"; |
809 | 809 | } |
810 | 810 | |
811 | 811 | if (keys %RSPSlaveChange) { |
812 | print "\nHigh-Availability Redundancy Feature, Card is manually reset, Slave is changinf state on device :\n"; | |
812 | print "\nHigh-Availability Redundancy Feature, Card is manually reset, Slave is changing state on device :\n"; | |
813 | 813 | foreach $ThisOne (sort keys %RSPSlaveChange) { |
814 | 814 | print " " . $ThisOne . ":\n"; |
815 | 815 | foreach $ThatOne (sort keys %{$RSPSlaveChange{$ThisOne}}) { |
969 | 969 | } |
970 | 970 | |
971 | 971 | if (keys %SYSWaitOnline) { |
972 | print "\nSupervisor engine in the process on beeing online on device :\n"; | |
972 | print "\nSupervisor engine in the process on being online on device :\n"; | |
973 | 973 | foreach $ThisOne (sort keys %SYSWaitOnline) { |
974 | 974 | print " " . $ThisOne . ":\n"; |
975 | 975 | foreach $ThatOne (sort keys %{$SYSWaitOnline{$ThisOne}}) { |
179 | 179 | ($ThisLine =~ /^Closing (?:-\d+ )listener on/) || |
180 | 180 | ($ThisLine =~ /^Called as: /) || |
181 | 181 | ($ThisLine =~ /(?:zlib| libcurl|libssh2)\/\d/) || |
182 | # ($ThisLine =~ /^\[\d+\]\[.+\]/) || # this conflics with the web stats | |
182 | # ($ThisLine =~ /^\[\d+\]\[.+\]/) || # this conflicts with the web stats | |
183 | 183 | ($ThisLine =~ /^Caught signal 15; shutting down/) || |
184 | 184 | ($ThisLine =~ /^\$Id\$/) || |
185 | 185 | ($ThisLine =~ /^errno is \d+$/) || |
1200 | 1200 | print_doubleline(); |
1201 | 1201 | } |
1202 | 1202 | } |
1203 | ## add connecitons | |
1203 | ## add connections | |
1204 | 1204 | print_asterisks(); |
1205 | 1205 | print_hash(\%SMTPserverFROM, "Envelope senders"); |
1206 | 1206 | print_hash(\%SMTPserverRCPT, "Recipients"); |
147 | 147 | print " echo \"*RemoveHeaders\" >> /etc/logwatch/conf/logfiles/clam-update.conf\n"; |
148 | 148 | } |
149 | 149 | |
150 | if ($Status) { | |
150 | if ($Status and (($Detail > 0) or (keys %Errors) or (keys %Warnings))) { | |
151 | 151 | print "\n" . $Status; |
152 | 152 | }; |
153 | 153 |
68 | 68 | ( $ThisLine =~ /^(?:LOCAL|TCP): Removing stale socket file/ ) or |
69 | 69 | ( $ThisLine =~ /Listening daemon: PID: / ) or |
70 | 70 | ( $ThisLine =~ /Bytecode: Security mode set to /) or |
71 | ( $ThisLine =~ /^No stats for Database check/ )) { | |
71 | ( $ThisLine =~ /^No stats for Database check/ ) or | |
72 | ( $ThisLine =~ /^Received \d+ file descriptor\(s\) from systemd\.$/ )) { | |
72 | 73 | # We do not care about these. |
73 | 74 | } elsif (my ($Check) = ($ThisLine =~ /^SelfCheck: (.*?)\.?\s?\n/i)) { |
74 | 75 | $SelfCheck{$Check}++; |
86 | 87 | } elsif (($ThisLine =~ /LOCAL: Unix socket file ([^ \n]*)/)) { |
87 | 88 | $SocketFile{$1}++; |
88 | 89 | } elsif (($ThisLine =~ /TCP: Bound to address ([^ ]*) on port (\d+)/)) { |
90 | $BoundToIP{$1}++; | |
91 | $BoundToPort{$1}=$2; | |
92 | } elsif (($ThisLine =~ /TCP: Bound to \[([^ ]+)\]:(\d+)/)) { | |
89 | 93 | $BoundToIP{$1}++; |
90 | 94 | $BoundToPort{$1}=$2; |
91 | 95 | } elsif (my ($Limit,$Value) = ($ThisLine =~ /Limits: (.*) limit (?:set to|is) (.*)\./)) { |
116 | 120 | } |
117 | 121 | } |
118 | 122 | |
119 | if ((keys %SelfCheck) and ($Detail >=5)) { | |
123 | if ((keys %SelfCheck) and ($Detail >= 5)) { | |
120 | 124 | print "\nDaemon check list:\n"; |
121 | 125 | foreach my $Check (sort {$a cmp $b} keys %SelfCheck) { |
122 | 126 | printf " %-50s %5i Time(s)\n", $Check .":", $SelfCheck{$Check}; |
123 | 127 | } |
124 | 128 | } |
125 | 129 | |
126 | if ($DatabaseReloads) { | |
130 | if ($DatabaseReloads and ($Detail > 0)) { | |
127 | 131 | print "\nVirus database reloaded $DatabaseReloads time(s) (last time with $DatabaseViruses viruses)\n"; |
128 | 132 | } |
129 | 133 |
26 | 26 | |
27 | 27 | while (defined($ThisLine = <STDIN>)) { |
28 | 28 | |
29 | chomp($ThisLine); | |
29 | 30 | if ( |
30 | 31 | ( $ThisLine =~ /^clamav-milter (startup|shutdown) succeeded$/ ) or |
32 | ( $ThisLine =~ /^clamav-milter started at/i ) or | |
33 | ( $ThisLine =~ /^(WARNING: )?No clamd server appears to be available/i ) or | |
31 | 34 | ( $ThisLine =~ /^Database has changed, loading updated database/ ) or |
32 | 35 | ( $ThisLine =~ /^Quarantined infected mail as/ ) or |
33 | 36 | ( $ThisLine =~ /^\w+ quarantined as/ ) or |
34 | ( $ThisLine =~ /^ClamAv: mi_stop/ ) or | |
37 | ( $ThisLine =~ /^ClamAv: mi_stop/i ) or | |
35 | 38 | ( $ThisLine =~ m#^\/tmp\/clamav-.* .* FOUND# ) or |
36 | 39 | # These two go along with "max-children limit" so we ignore them |
37 | 40 | ( $ThisLine =~ /n_children \d+: waiting \d+ seconds for some to exit/ ) or |
48 | 48 | |
49 | 49 | use strict; |
50 | 50 | |
51 | #Could be neccessary in some environments | |
51 | #Could be necessary in some environments | |
52 | 52 | unless ($ENV{'courier_enable'} == 1) {exit 0}; |
53 | 53 | |
54 | 54 | my $Debug = $ENV{'LOGWATCH_DEBUG'}; |
385 | 385 | chomp $ThisLine; |
386 | 386 | my $Size2 = 0; |
387 | 387 | my $Size = 0; |
388 | #TODO: Make this more accurrate (expand to \d+ times) | |
388 | #TODO: Make this more accurate (expand to \d+ times) | |
389 | 389 | if ( $ThisLine =~ /^... .. ..:..:.. \S+ last message repeated \d+ times/ ) { |
390 | 390 | $ThisLine = $LastLine; |
391 | 391 | } else { |
93 | 93 | $BFMFile{$FileName}++; |
94 | 94 | } elsif ( ($FileName) = ($ThisLine =~ /WRONG FILE OWNER \((.+)\)/) ) { |
95 | 95 | $WFO{$FileName}++; |
96 | } elsif ($ThisLine =~ /NULL security context for user, but SELinux in permissive mode/ ) { | |
97 | $SELCONTErr{$ThisLine}++; | |
96 | 98 | } else { |
97 | 99 | # Report any unmatched entries... |
98 | 100 | push @OtherList, "$ThisLine\n"; |
269 | 271 | print " system table " . $key . " created " . $INCRONDSTCr{$key} . ": time(s)\n"; |
270 | 272 | } |
271 | 273 | for $key (keys %INCRONDUTCr) { |
272 | print " table for user " . $key . " ceated " . $INCRONDUTCr{$key}. ": time(s)\n"; | |
274 | print " table for user " . $key . " created " . $INCRONDUTCr{$key}. ": time(s)\n"; | |
273 | 275 | } |
274 | 276 | } |
275 | 277 | |
315 | 317 | } |
316 | 318 | |
317 | 319 | if ($PAMAUTHErr) { |
318 | printf "\nPAM autentification error: " . $PAMAUTHErr . " time(s)\n"; | |
320 | printf "\nPAM authentication error: " . $PAMAUTHErr . " time(s)\n"; | |
319 | 321 | } |
320 | 322 | |
321 | 323 | if (%CHDIRErr) { |
41 | 41 | ($line =~ /^Please contribute if you find this software useful/) or |
42 | 42 | ($line =~ /^For info, please visit/) or |
43 | 43 | # Other lines to ignore |
44 | ($line =~ /^Wrote .* to leases file\./) or | |
44 | ($line =~ /^Wrote .* to lease(s)? file\./) or | |
45 | 45 | ($line =~ /^already acking lease/) or |
46 | 46 | ($line =~ /^dhcpd shutdown .*succeeded/) or |
47 | 47 | ($line =~ /^dhcpd startup .*succeeded/) or |
48 | ($line =~ /^Server starting service\./) or | |
49 | ($line =~ /^Source compiled to use binary-leases/) or | |
50 | ($line =~ /^WARNING: authoring-byte-order not in the lease file/) or | |
48 | 51 | ($line =~ /^Sending on/) or |
49 | 52 | ($line =~ /^Dynamic and static leases present for/) or |
50 | 53 | # backup server pool balancing |
69 | 72 | ($line =~ /^Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not specified in the config file/) or |
70 | 73 | ($line =~ /^Solicit message from/) or |
71 | 74 | ($line =~ /^Sending Advertise to/) or |
72 | ($line =~ /^pool [0-9a-f]+ /) | |
75 | ($line =~ /^pool [0-9a-f]+ /) or | |
76 | ($line =~ /^[^ ]* file: /) | |
73 | 77 | ) { |
74 | 78 | # Ignore these lines |
75 | 79 | } elsif ($line =~ s/Listening on\s+//) { |
76 | 80 | if ($Detail >= 5) { |
77 | 81 | $data{'DHCP Server Listening On'}{$line}++; |
78 | 82 | } |
83 | } elsif ($line =~ s/Bound to\s+//) { | |
84 | $data{'DHCP Server Listening On'}{$line}++; | |
79 | 85 | } elsif ( |
80 | 86 | ($line =~ /^you want, please write a subnet declaration/) or |
81 | 87 | ($line =~ /^in your dhcpd.conf file for the network segment/) or |
124 | 130 | $data{'Config error'}{$line}++; |
125 | 131 | } elsif ($line =~ /host unknown/) { |
126 | 132 | $data{'Config error'}{$line}++; |
133 | } elsif ($line =~ s/^ldap_gssapi_principal is not set,//) { | |
134 | $data{'Config error'}{$line}++; | |
127 | 135 | } elsif ($line =~ s/^DHCPOFFER on ([\d\.]+) to ([a-f\d:]+) via (\S+)\s*$/$1 -> $2 ($3)/) { |
128 | 136 | if ($Detail >= 5) { |
129 | 137 | $data{'Addresses Leased'}{$line}++; |
158 | 166 | } elsif (($Detail >= 10) and ($clientrequest =~ /Rebind|Renew/)) { |
159 | 167 | $data{"Addresses $clientrequest"}{$line}++; |
160 | 168 | } |
169 | } elsif ($line =~ s/^(Advertise|Reply) ([TN]A): address ([0-9a-fA-F:]+) to client with duid ([0-9a-fA-F:]+) iaid = [-\d]+( static)?/$3 ($2$5) -> DUID $4/) { | |
170 | $data{"Addresses $1"}{$line}++; | |
161 | 171 | } elsif ($line =~ /^Client ([0-9a-fA-F:]+) releases address ([0-9a-fA-F:]+), which is not leased to it.$/) { |
162 | 172 | if ($Detail >= 5) { |
163 | 173 | $data{'Warnings'}{$line}++; |
210 | 220 | if ($Detail >= 3) { |
211 | 221 | $data{'Duplicate lease'}{$line}++; |
212 | 222 | } |
213 | } elsif ($line =~ /^DHCPDISCOVER from .* via \S+: (.*): no free leases/) { | |
214 | $data{'No Free Leases'}{$1}++; | |
223 | } elsif ($line =~ /^DHCPDISCOVER from (.*) via \S+: (.*): no free leases/) { | |
224 | $data{'No Free Leases'}{"$2: $1"}++; | |
215 | 225 | } elsif ($line =~ /^DHCPDISCOVER from .* via (\S+): unknown network segment/) { |
216 | 226 | $data{'Unknown Network Segments'}{$1}++; |
217 | 227 | } elsif ($line =~ /^DHCPDISCOVER from .* via (\S+): load balance to peer/) { |
33 | 33 | chomp($ThisLine); |
34 | 34 | |
35 | 35 | if ($ThisLine =~ /^Listening for new connections again$/ |
36 | or $ThisLine =~ /^Beginning export of / | |
37 | or $ThisLine =~ /^Export finished/ | |
36 | 38 | or $ThisLine =~ /Listening on .* (for LDAPI requests|port)/ |
37 | 39 | or $ThisLine =~ /^Waiting for \d+ database threads to stop/ |
38 | 40 | or $ThisLine =~ /^slapd shutting down - / |
39 | 41 | or $ThisLine =~ /^SSL alert: Configured NSS Ciphers$/ |
40 | 42 | or $ThisLine =~ /^ldbm_back_.* - conn=/ |
41 | 43 | or $ThisLine =~ /^ldbm_usn_init - backend: / |
44 | # https://pagure.io/389-ds-base/issue/48973 | |
45 | or $ThisLine =~ /^default_mr_indexer_create: warning - plugin \[caseIgnoreIA5Match\] does not handle caseExactIA5Match/ | |
42 | 46 | ) { |
43 | 47 | #Ignore |
44 | } elsif ($ThisLine =~ /error/i | |
48 | } elsif ($ThisLine =~ /^ERR - / | |
49 | or $ThisLine =~ /error/i | |
45 | 50 | or $ThisLine =~ /^Detected Disorderly Shutdown/) { |
46 | 51 | $Errors{$ThisLine}++; |
47 | } elsif ($ThisLine =~ /warning/i | |
52 | } elsif ($ThisLine =~ /^WARN - / | |
53 | or $ThisLine =~ /warning/i | |
48 | 54 | or $ThisLine =~ /^Not listening for new connections/) { |
49 | 55 | $Warnings{$ThisLine}++; |
50 | 56 | } elsif ($ThisLine =~ /^(.*) starting up$/) { |
72 | 78 | #This line follows the previous normally in backups or shutdown |
73 | 79 | $OtherList{$ThisLine}++ unless $PreviousLine =~ /^(export \w+: Processed \d+ entries|Waiting for \d+ database threads to stop|Backing up file|Copying .* to )/; |
74 | 80 | } else { |
81 | next if $ThisLine =~ /^INFO -/ and $Detail < 10; | |
82 | next if $ThisLine =~ /^NOTICE -/ and $Detail < 5; | |
75 | 83 | $OtherList{$ThisLine}++; |
76 | 84 | } |
77 | 85 | $PreviousLine = $ThisLine; |
140 | 148 | } |
141 | 149 | |
142 | 150 | if (keys %NSSCiphers and $Detail >= 7) { |
143 | print "\nNSS Cipers:\n"; | |
151 | print "\nNSS Ciphers:\n"; | |
144 | 152 | foreach my $Cipher (sort {$a cmp $b} keys %NSSCiphers) { |
145 | 153 | print " $Cipher: $NSSCiphers{$Cipher}\n"; |
146 | 154 | } |
0 | ||
1 | ####################################################### | |
2 | ## Copyright (c) 2008 Sy Beamont <sbeam@attbi.com> | |
3 | ## Covered under the included MIT/X-Consortium License: | |
4 | ## http://www.opensource.org/licenses/mit-license.php | |
5 | ## All modifications and contributions by other persons to | |
6 | ## this script are assumed to have been donated to the | |
7 | ## Logwatch project and thus assume the above copyright | |
8 | ## and licensing terms. If you want to make contributions | |
9 | ## under your own copyright or a different license this | |
10 | ## must be explicitly stated in the contribution an the | |
11 | ## Logwatch project reserves the right to not accept such | |
12 | ## contributions. If you have made significant | |
13 | ## contributions to this script and want to claim | |
14 | ## copyright please contact logwatch-devel@lists.sourceforge.net. | |
15 | ######################################################### | |
16 | ||
17 | $Debug = $ENV{'LOGWATCH_DEBUG'} || 0; | |
18 | ||
19 | if ( $Debug >= 5 ) { | |
20 | print STDERR "\n\nDEBUG: Inside dnf-rpm Filter \n\n"; | |
21 | $DebugCounter = 1; | |
22 | } | |
23 | ||
24 | while (defined($ThisLine = <STDIN>)) { | |
25 | if ( $Debug >= 5 ) { | |
26 | print STDERR "DEBUG($DebugCounter): $ThisLine"; | |
27 | $DebugCounter++; | |
28 | } | |
29 | ||
30 | if ( $ThisLine =~ s/^.* INFO Upgraded: ([^ ]+)/$1/ ) { | |
31 | $PackageUpdated{$ThisLine}++; | |
32 | } elsif ( $ThisLine =~ s/^.* INFO Installed: ([^ ]+)/$1/ ) { | |
33 | $PackageInstalled{$ThisLine}++; | |
34 | } elsif ( $ThisLine =~ s/^.* INFO Erased: ([^ ]+)/$1/ ) { | |
35 | $PackageErased{$ThisLine}++; | |
36 | } elsif ( $ThisLine =~ m/INFO --- logging initialized ---/ ) { | |
37 | $ignoredlines++; | |
38 | } elsif ( $ThisLine =~ m/INFO Cleanup: / ) { | |
39 | $ignoredlines++; | |
40 | } else { | |
41 | # Report any unmatched entries... | |
42 | push @OtherList,$ThisLine; | |
43 | } | |
44 | } | |
45 | ||
46 | if (keys %PackageInstalled) { | |
47 | print "\nPackages Installed:\n"; | |
48 | foreach $ThisOne (sort {lc($a) cmp lc($b)} keys %PackageInstalled) { | |
49 | print " " . $ThisOne; | |
50 | } | |
51 | } | |
52 | if (keys %PackageUpdated) { | |
53 | print "\nPackages Updated:\n"; | |
54 | foreach $ThisOne (sort {lc($a) cmp lc($b)} keys %PackageUpdated) { | |
55 | print " ". $ThisOne; | |
56 | } | |
57 | } | |
58 | if (keys %PackageErased) { | |
59 | print "\nPackages Erased:\n"; | |
60 | foreach $ThisOne (sort {lc($a) cmp lc($b)} keys %PackageErased) { | |
61 | print " ". $ThisOne; | |
62 | } | |
63 | } | |
64 | ||
65 | if ($#OtherList >= 0) { | |
66 | print "\n**Unmatched Entries**\n"; | |
67 | print @OtherList; | |
68 | } | |
69 | ||
70 | exit(0); | |
71 | ||
72 | # vi: shiftwidth=3 tabstop=3 syntax=perl et | |
73 | # Local Variables: | |
74 | # mode: perl | |
75 | # perl-indent-level: 3 | |
76 | # indent-tabs-mode: nil | |
77 | # End: |
39 | 39 | # These scripts were created as part of the dnssec-tools project. |
40 | 40 | # For more information, see http://sourceforge.net/dnssec-tools. |
41 | 41 | # Detailed instructions for setting up BIND 9.3.* to use these logwatch |
42 | # configuration files and scripts are containted in the README file | |
42 | # configuration files and scripts are contained in the README file | |
43 | 43 | # on sourceforge. |
44 | 44 | ############################################################################# |
45 | 45 |
111 | 111 | my %DiskQuotaExceed; |
112 | 112 | my %Deliver; |
113 | 113 | my %DeliverUserCount; |
114 | my %Error; | |
115 | my %Fatal; | |
114 | 116 | my %Forwarded; |
115 | 117 | my %LimitExceeded; |
116 | 118 | my %Login; |
176 | 178 | ($ThisLine =~ /Connection closed/) or |
177 | 179 | ($ThisLine =~ /IMAP.*: Connection closed bytes/) or |
178 | 180 | ($ThisLine =~ /IMAP.* failed with mbox file/) or |
179 | ($ThisLine =~ /discarded duplicate forward to/) or | |
181 | ($ThisLine =~ /discarded duplicate forward to/) or | |
180 | 182 | ($ThisLine =~ /discarding vacation response/) or |
181 | ($ThisLine =~ /discarded vacation reply to/) | |
183 | ($ThisLine =~ /discarded vacation reply to/) or | |
184 | ($ThisLine =~ /Debug:/) or | |
185 | 0 # This line prevents blame shifting as lines are added above | |
182 | 186 | ) |
183 | { | |
187 | { | |
184 | 188 | # We don't care about these |
185 | 189 | } elsif ( $ThisLine =~ /Killed with signal /) { |
186 | 190 | $End++; |
187 | } elsif ( $ThisLine =~ /Dovecot (v\d[^ ]* |)starting up/) { | |
191 | } elsif ( $ThisLine =~ /Dovecot (v\d[^ ]* |)(\([0-9a-fA-F]+\) )?starting up/) { | |
188 | 192 | $Restarts++; |
189 | 193 | $End = 0; |
190 | 194 | } elsif ( (my ($User, $Host) = ( $ThisLine =~ /^(?:$dovecottag )?pop3-login: Login: (.*?) \[(.*)\]/ ) ) or |
216 | 220 | # 'lda' for dovecot 2.0, 'deliver' for earlier versions |
217 | 221 | } elsif (my ($User, $Mailbox) = ( $ThisLine =~ /^$dovecottag (?:lda|deliver)\((.*)\): msgid=.*: saved mail to (.*)/ ) ) { |
218 | 222 | $Deliver{$User}{$Mailbox}++; |
219 | ||
223 | } elsif ( ($User, $Mailbox) = ( $ThisLine =~ /^$dovecottag service=lda, user=(.*), .* msgid=.*: saved mail to (.*)/ ) ) { | |
224 | $Deliver{$User}{$Mailbox}++; | |
220 | 225 | # For Sieve-based delivery |
221 | 226 | } elsif (my ($User, $Mailbox) = ( $ThisLine =~ /^$dovecottag (?:lda|deliver)\((.*)\): sieve: msgid=.*: stored mail into mailbox '(.*)'/ ) ) { |
222 | 227 | $Deliver{$User}{$Mailbox}++; |
276 | 281 | $Disconnected{$Reason}++; |
277 | 282 | } elsif (my ($Reason) = ($ThisLine =~ /Disconnected: (.*) (bytes|top|in)=.*/) ) { |
278 | 283 | $Disconnected{$Reason}++; |
279 | } elsif ($ThisLine =~ /Logged out (bytes|top|in)=.*/) { | |
284 | } elsif ($ThisLine =~ /Logged out (rcvd|bytes|top|in)=.*/) { | |
280 | 285 | $Disconnected{"Logged out"}++; |
281 | 286 | } elsif (my ($Reason) = ($ThisLine =~ /Disconnected \((.*)\):/) ) { |
282 | 287 | $Reason =~ s/ in \d+ secs//; |
339 | 344 | } elsif (my ($User,$MUA) = ($ThisLine =~ /imap\((.*)\): ID sent: name=(.*)/)) { |
340 | 345 | $MUAList{$MUA}{$User}++; |
341 | 346 | # These are failed connections with imap_id_log = * enabled |
342 | } elsif ($ThisLine =~ /imap-login: ID sent: name=/) { | |
347 | } elsif ($ThisLine =~ /imap-login: ID sent: (?:name|vendor)=/) { | |
343 | 348 | # Ignore |
349 | } elsif (my ($Fatal) = ($ThisLine =~ /^(?:$dovecottag )?(.* Fatal:.*)/)) { | |
350 | $Fatal{$Fatal}++; | |
351 | } elsif (my ($Error) = ($ThisLine =~ /^(?:$dovecottag )?(.* Error:.*)/)) { | |
352 | $Error{$Error}++; | |
344 | 353 | } else { |
345 | 354 | # Report any unmatched entries... |
346 | 355 | chomp($ThisLine); |
352 | 361 | |
353 | 362 | if ( $End ) { |
354 | 363 | print "\nDovecot was killed, and not restarted afterwards.\n"; |
364 | } | |
365 | ||
366 | if ( keys %Fatal ) { | |
367 | print "\nDovecot Fatal Errors:\n"; | |
368 | foreach my $Fatal (sort keys %Fatal) { | |
369 | print " ${Fatal}: $Fatal{$Fatal} Time(s)\n"; | |
370 | } | |
371 | } | |
372 | ||
373 | if ( keys %Error ) { | |
374 | print "\nDovecot Errors:\n"; | |
375 | foreach my $Error (sort keys %Error) { | |
376 | print " ${Error}: $Error{$Error} Time(s)\n"; | |
377 | } | |
355 | 378 | } |
356 | 379 | |
357 | 380 | if ( ( $Detail >=5 ) and $Restarts ) { |
75 | 75 | } elsif ( $ThisLine =~ s/^Dep Installed: ([^ ]+)/$1 / ) { |
76 | 76 | $PackageDepInstalled{$ThisLine}++; |
77 | 77 | } elsif ( $ThisLine =~ /exiting unsuccessfully with status \'(\d)\'/ ) { |
78 | $ExitUnsuccessfull{$1}++; | |
78 | $ExitUnsuccessful{$1}++; | |
79 | 79 | } else { |
80 | 80 | # Report any unmatched entries... |
81 | 81 | push @OtherList,$ThisLine; |
115 | 115 | print " ". $ThisOne; |
116 | 116 | } |
117 | 117 | } |
118 | if (keys %ExitUnsuccessfull) { | |
118 | if (keys %ExitUnsuccessful) { | |
119 | 119 | print "\nUnsuccessfull exit with:\n"; |
120 | foreach $ThisOne (keys %ExitUnsuccessfull) { | |
121 | print " Status $ThisOne : $ExitUnsuccessfull{$ThisOne} Time(s)\n"; | |
120 | foreach $ThisOne (keys %ExitUnsuccessful) { | |
121 | print " Status $ThisOne : $ExitUnsuccessful{$ThisOne} Time(s)\n"; | |
122 | 122 | } |
123 | 123 | } |
124 | 124 |
308 | 308 | } |
309 | 309 | |
310 | 310 | if (keys %WorkstationLocked and ($Detail >= 10)) { |
311 | print "\nWorkstaion Locked\n"; | |
311 | print "\nWorkstation Locked\n"; | |
312 | 312 | foreach my $User (sort keys %WorkstationLocked) { |
313 | 313 | print " $User : $WorkstationLocked{$User} Times\n"; |
314 | 314 | } |
315 | 315 | } |
316 | 316 | |
317 | 317 | if (keys %WorkstationUnlocked and ($Detail >= 10)) { |
318 | print "\nWorkstaion Unlocked\n"; | |
318 | print "\nWorkstation Unlocked\n"; | |
319 | 319 | foreach my $User (sort keys %WorkstationUnlocked) { |
320 | 320 | print " $User : $WorkstationUnlocked{$User} Times\n"; |
321 | 321 | } |
57 | 57 | } |
58 | 58 | #print STDERR "ExpandedString = $ExpandedString\n"; |
59 | 59 | |
60 | next if ($EventLogType eq "Information" and $Detail < 10); | |
61 | ||
60 | 62 | if ($System eq "Application Popup") { |
61 | 63 | #Ignore these |
62 | 64 | next if $ExpandedString =~ /Initialization Failed : The application failed to initialize because the window station is shutting down/; |
49 | 49 | $LvlBadFormat = $ENV{'exim_misformat'} || 0; |
50 | 50 | $LvlRestarts = $ENV{'exim_restart'} || 5; |
51 | 51 | $LvlVirus = $ENV{'exim_virus'} || 0; |
52 | $LvlProtocl = $ENV{'exim_protocol'} || 0; | |
53 | $LvlProtoclLines = $ENV{'exim_protocol_lines'}|| 5; | |
52 | $LvlProtocol = $ENV{'exim_protocol'} || 0; | |
53 | $LvlProtocolLines = $ENV{'exim_protocol_lines'}|| 5; | |
54 | 54 | $LvlDontAccept = $ENV{'exim_dontaccept'} || 0; |
55 | 55 | $LvlDontAcceptLines = $ENV{'exim_dontaccept_lines'} || 0; |
56 | 56 | $LvlVerify = $ENV{'exim_verify'} || 0; |
79 | 79 | # IPv6 part could be made more strict |
80 | 80 | my $IPAddress = qr/\d+\.\d+\.\d+\.\d+|[a-fA-F0-9]*:[a-fA-F0-9:]+/; |
81 | 81 | |
82 | my $MatchedDate = 0; | |
83 | ||
82 | 84 | while (defined($ThisLine = <STDIN>)) { |
83 | 85 | chomp($ThisLine); |
84 | 86 | # pobierz dzisiejsza date z 2002-03-31 22:13:48 ... |
85 | 87 | # Collect this line's date, e.g. 2002-03-31 22:13:48 ... |
86 | 88 | do { |
89 | if ( $ThisLine =~ /^ Suggested action: use keep_environment./ ) { | |
90 | $KeepEnv++ if $MatchedDate; | |
91 | next; | |
92 | } | |
87 | 93 | $BadFormat{$ThisLine}++; |
88 | 94 | next; |
89 | 95 | } unless ($year1,$month1,$day1,$h1,$m1,$s1) = ($ThisLine =~ /^(\d+)\-(\d+)\-(\d+)\s(\d+):(\d+):(\d+)\s.+/); |
90 | 96 | |
91 | next unless $ThisLine =~ /^$SearchDate /o; | |
97 | unless ($ThisLine =~ /^$SearchDate /o) { | |
98 | $MatchedDate = 0; | |
99 | next; | |
100 | } | |
101 | $MatchedDate = 1; | |
92 | 102 | |
93 | 103 | if ( $ThisLine =~ /End queue run\:/ ) { |
94 | 104 | $EndQueue++; |
113 | 123 | } |
114 | 124 | elsif ( $ThisLine =~ /[Ss]ender verify fail/ ) { |
115 | 125 | $SendVerify{$ThisLine}++; |
126 | } | |
127 | elsif ( $ThisLine =~ /Warning: purging the environment./ ) { | |
128 | $Purging++; | |
116 | 129 | } |
117 | 130 | elsif ( $ThisLine =~ /fragments administratively prohib/ ) { |
118 | 131 | $DontAccept{$ThisLine}++; |
203 | 216 | } |
204 | 217 | elsif ( $ThisLine =~ /SMTP protocol error in \"\w+\"/ ) { |
205 | 218 | # Some hosts ask for TLS even when not offered (generalised to all cmds) |
219 | $Proto{$ThisLine}++; | |
220 | } | |
221 | elsif ( $ThisLine =~ /TLS error on connection from (\S+) \(([^)]*)\) \[(\S+)\]:(\d+) I=\[(\S+)\]:(\d+) \(send\): Error in the push function\./ ) { | |
222 | # Ignore this, office 365 connector early disconnect. | |
223 | } | |
224 | elsif ( $ThisLine =~ /authenticator failed for/ ) { | |
206 | 225 | $Proto{$ThisLine}++; |
207 | 226 | } |
208 | 227 | elsif ( $ThisLine =~ /Connection from .* too many connections from that IP address/ ) { |
275 | 294 | print " $ThisOne\n"; |
276 | 295 | } |
277 | 296 | } |
297 | } | |
298 | ||
299 | if ($Purging) { | |
300 | print " Warning: purging the environment. : $Purging Time(s)\n"; | |
301 | } | |
302 | if ($KeepEnv) { | |
303 | print " ... Suggested action: use keep_environment. : $KeepEnv Time(s)\n"; | |
278 | 304 | } |
279 | 305 | |
280 | 306 | if ($Detail >= $LvlRuns) { |
355 | 381 | # Link date and time (looks cleaner)... |
356 | 382 | $aa = "$mdate $mtime"; |
357 | 383 | # Extract the REAL IP address... |
358 | ($bb) = ($ThisOne =~ m/\s\[($IPAddress)\]\s/); | |
384 | ($bb) = ($ThisOne =~ m/\s\[($IPAddress)\][\s:]/); | |
359 | 385 | # Exim >= 4.50 compiled with, WITH_CONTENT_SCAN=yes |
360 | 386 | # Default warning looks like this... |
361 | 387 | # rejected after DATA: This message contains a [vV]irus (%s). |
507 | 533 | } |
508 | 534 | } |
509 | 535 | |
510 | if ($Detail >= $LvlProtocl) { | |
536 | if ($Detail >= $LvlProtocol) { | |
511 | 537 | # Print Protocol Violations |
512 | 538 | if (%Proto) { |
513 | 539 | my (%spam); |
581 | 607 | $bb = $1; |
582 | 608 | $SmtpConnection{$bb}++; |
583 | 609 | } |
610 | elsif ( $ThisOne =~ /authenticator failed for \([^)]*\) \[($IPAddress)\]:\d+ I=\[$IPAddress\]:\d+: (.*) \(/ ) { | |
611 | $bb = $1; | |
612 | $SmtpConnection{$bb}++; | |
613 | } | |
584 | 614 | elsif ( $ThisOne =~ /SMTP connection from/ ) { |
585 | 615 | if ( $ThisOne =~ /lost while reading message data/ ) { |
586 | 616 | $bb = "SMTP connection lost while reading message data"; |
622 | 652 | } |
623 | 653 | } |
624 | 654 | foreach $ThisOne (sort(keys %spam)) { |
625 | if ($Detail >= $LvlProtoclLines) { | |
655 | if ($Detail >= $LvlProtocolLines) { | |
626 | 656 | print " $ThisOne:\n"; |
627 | 657 | foreach $aa ( sort( split /,/, $spam{$ThisOne} )) { |
628 | 658 | print " $aa\n"; |
646 | 676 | print "\n--- Failed Reverse Lookups \n"; |
647 | 677 | print "--- $ReverseLookup Time(s)\n\n"; |
648 | 678 | |
649 | if ($Detail >= $LvlProtoclLines) { | |
679 | if ($Detail >= $LvlProtocolLines) { | |
650 | 680 | foreach $ThisOne (@ReverseLookupH) { |
651 | 681 | print " $ThisOne\n"; |
652 | 682 | } |
657 | 687 | print "\n--- Failed Reverse Lookups \n"; |
658 | 688 | print "--- (eg. spam try): $Lookup Time(s)\n\n"; |
659 | 689 | |
660 | if ($Detail >= $LvlProtoclLines) { | |
690 | if ($Detail >= $LvlProtocolLines) { | |
661 | 691 | foreach $ThisOne (@LookupH) { |
662 | 692 | print "$ThisOne\n"; |
663 | 693 | } |
118 | 118 | $ServicesFound{$Service}{$Host}++; |
119 | 119 | } elsif ( my ($Service,$Host) = ($ThisLine =~ /INFO\s+\[(.*)\] Ignore (.*)/)) { |
120 | 120 | $ServicesIgnored{$Service}{$Host}++; |
121 | # Generice messages | |
121 | # Generic messages | |
122 | 122 | } elsif ( my ($Message) = ($ThisLine =~ / ERROR (.*)$/)) { |
123 | 123 | $ErrorList{$Message}++; |
124 | 124 | } elsif ( my ($Message) = ($ThisLine =~ / WARNING (.*)$/)) { |
61 | 61 | my %ban_ip =(); |
62 | 62 | my %robots =(); |
63 | 63 | my $pattern = ""; |
64 | my $flag = 0; | |
65 | 64 | my $isahack = 0; |
66 | 65 | my $a5xx_resp = 0; |
67 | 66 | my $a4xx_resp = 0; |
235 | 234 | ); |
236 | 235 | |
237 | 236 | # |
238 | # Define some useful RE paterns | |
237 | # Define some useful RE patterns | |
239 | 238 | # |
240 | 239 | |
241 | 240 | my %re_pattern = ( |
592 | 591 | # List (wannabe) blackhat sites |
593 | 592 | # |
594 | 593 | |
595 | $flag = 1; | |
596 | foreach my $i (sort keys %ban_ip) { | |
597 | if ($flag) { | |
598 | print "\nA total of ".scalar(keys %ban_ip)." sites probed the server \n"; | |
599 | $flag = 0; | |
600 | } | |
601 | #if ($detail > 4) { | |
602 | print " $i\n"; | |
603 | #} | |
594 | if (keys %ban_ip and $detail) { | |
595 | print "\nA total of ".scalar(keys %ban_ip)." sites probed the server \n"; | |
596 | if ($detail > 4) { | |
597 | foreach my $i (sort keys %ban_ip) { | |
598 | print " $i\n"; | |
599 | } | |
600 | } | |
604 | 601 | } |
605 | 602 | |
606 | 603 | # |
607 | 604 | # List possible successful probes |
608 | 605 | # |
609 | 606 | |
610 | $flag = 1; | |
611 | 607 | if (keys %hack_success) { |
612 | 608 | print "\nA total of " . scalar(keys %hack_success) . " possible successful probes were detected (the following URLs\n"; |
613 | 609 | print "contain strings that match one or more of a listing of strings that\n"; |
622 | 618 | # List error response codes |
623 | 619 | # |
624 | 620 | |
625 | if (keys %needs_exam) { | |
621 | if (keys %needs_exam and ($detail or $a5xx_resp)) { | |
626 | 622 | print "\nRequests with error response codes\n"; |
627 | # my $count = TotalCountOrder(%needs_exam); | |
628 | 623 | for my $code (sort keys %needs_exam) { |
629 | 624 | if (not defined $StatusCode{$code}) { |
630 | 625 | $StatusCode{$code} = "\(undefined\)"; |
631 | 626 | } |
632 | if( ($ENV{"http_rc_detail_rep_$code"} || $detail) > $detail ) { | |
633 | # only display summary for this code | |
634 | my $t = 0; | |
635 | my $u = 0; | |
636 | foreach my $k ( keys %{$needs_exam{$code}}) { | |
637 | $u += 1; | |
638 | $t += $needs_exam{$code}{$k}; | |
639 | } | |
640 | print " $code $StatusCode{$code} SUMMARY - $u URLs, total: $t Time(s)\n"; | |
641 | } else { | |
642 | print " $code $StatusCode{$code}\n"; | |
643 | for my $url (sort { ($needs_exam{$code}{$b} <=> $needs_exam{$code}{$a}) or ($a cmp $b) } keys %{$needs_exam{$code}}) { | |
644 | print " $url: $needs_exam{$code}{$url} Time(s)\n"; | |
627 | if ($detail || ($code >= 500) || (($ENV{"http_rc_detail_rep_$code"} || $detail) < $detail)) { | |
628 | if ( ($ENV{"http_rc_detail_rep_$code"} || $detail) > $detail ) { | |
629 | # only display summary for this code | |
630 | my $t = 0; | |
631 | my $u = 0; | |
632 | foreach my $k ( keys %{$needs_exam{$code}}) { | |
633 | $u += 1; | |
634 | $t += $needs_exam{$code}{$k}; | |
635 | } | |
636 | print " $code $StatusCode{$code} SUMMARY - $u URLs, total: $t Time(s)\n"; | |
637 | } else { | |
638 | print " $code $StatusCode{$code}\n"; | |
639 | for my $url (sort { ($needs_exam{$code}{$b} <=> $needs_exam{$code}{$a}) or ($a cmp $b) } keys %{$needs_exam{$code}}) { | |
640 | print " $url: $needs_exam{$code}{$url} Time(s)\n"; | |
641 | } | |
645 | 642 | } |
646 | 643 | } |
647 | 644 | } |
671 | 668 | # List robots that identified themselves |
672 | 669 | # |
673 | 670 | |
674 | if ($detail > 4) { | |
675 | $flag = 1; | |
671 | if (keys %robots and ($detail > 4)) { | |
672 | print "\nA total of ".scalar(keys %robots)." ROBOTS were logged \n"; | |
676 | 673 | foreach my $i (keys %robots) { |
677 | if ($flag) { | |
678 | print "\nA total of ".scalar(keys %robots)." ROBOTS were logged \n"; | |
679 | $flag = 0; | |
680 | } | |
681 | 674 | if ($detail > 9) { |
682 | 675 | print " $i $robots{$i} Time(s) \n"; |
683 | 676 | } |
75 | 75 | foreach my $LogLevel (keys %LogMessages) { |
76 | 76 | printf("\nLevel %-6s", $LogLevel); |
77 | 77 | foreach my $ErrorCode (keys %{$LogMessages{$LogLevel}}) { |
78 | print "\n Error Code: $ErrorCode" if $Detail >= 5; | |
78 | print "\n $LogLevel code: $ErrorCode" if $Detail >= 5; | |
79 | 79 | foreach my $Description (keys %{$LogMessages{$LogLevel}{$ErrorCode}}) { |
80 | 80 | if ($Detail >= 9) { |
81 | 81 | print "\n $Description: "; |
163 | 163 | $CountSpaceLength = 12 - $CountLength; |
164 | 164 | $SSLLength = length("$SSL"); |
165 | 165 | $SSLSpaceLength = 9 - $SSLLength; |
166 | $TotalLenght = length("$Total"); | |
167 | $TotalSpaceLength = 10 - $TotalLenght; | |
166 | $TotalLength = length("$Total"); | |
167 | $TotalSpaceLength = 10 - $TotalLength; | |
168 | 168 | print "\n" ." " x $HostSpaceLength . $Host . " |" . " " x $CountSpaceLength . $Conns . |
169 | 169 | " |" . " " x $SSLSpaceLength . $SSL . " |" . " " x $TotalSpaceLength . $Total; |
170 | 170 | $NonSSLCount += $Conns; |
6 | 6 | # Revision 0.2 2002/05/29 Pawel Jarosz <pj@rsi.pl> |
7 | 7 | # - More flexible output |
8 | 8 | # Revision 0.1 2002/05/27 Pawel Jarosz <pj@rsi.pl> |
9 | # - Removed unneded things | |
9 | # - Removed unneeded things | |
10 | 10 | # - New lookout, more sorted data |
11 | 11 | ########################################################################## |
12 | 12 |
67 | 67 | my %Errors = (); |
68 | 68 | my %Kernel = (); |
69 | 69 | my %EDACs = (); |
70 | my %NFS = (); | |
71 | my %EXT4Volume = (); | |
72 | my %EXT4 = (); | |
70 | 73 | |
71 | 74 | while (defined(my $ThisLine = <STDIN>)) { |
72 | 75 | chomp($ThisLine); |
81 | 84 | # following now in iptables service |
82 | 85 | or ($ThisLine =~ /^Packet log: .*PROTO=/) |
83 | 86 | or ($ThisLine =~ /IN=.*OUT=.*SRC=.*DST=.*PROTO=/) |
87 | or ($ThisLine =~ /RAS: Correctable Errors collector initialized/) | |
84 | 88 | # user specified ignore messages, lower cased |
85 | 89 | or ($ThisLine =~ /$Ignore_messages/i) |
86 | 90 | ) { # ignore the above strings |
130 | 134 | $SkipError = 1 if $ThisLine =~ /PCIe errors handled by (?:BIOS|OS)/; |
131 | 135 | # These happen when kerberos tickets expire, which can be normal |
132 | 136 | $SkipError = 1 if $ThisLine =~ /Error: state manager encountered RPCSEC_GSS session expired against NFSv4 server/ && $Ignore_rpcsec_expired; |
137 | $SkipError = 1 if $ThisLine =~ /RAS: Correctable Errors collector initialized/; | |
133 | 138 | # filter out mount options |
134 | 139 | $SkipError = 1 if $ThisLine =~ /errors=(?:continue|remount-ro|panic)/; |
135 | 140 | $Errors{$errormsg}++ if ( (! $SkipError) || ($Detail > 8)); |
141 | } elsif ( ( my ($Volume, $errormsg) ) = ( $ThisLine =~ /^EXT4-fs \(([^)]+)\): (.*)/ ) ) { | |
142 | if ($errormsg =~ /INFO: recovery required on readonly filesystem/) { | |
143 | $EXT4Volume{$Volume} = 1; | |
144 | push @{$EXT4{$Volume}}, $errormsg; | |
145 | } elsif ($EXT4Volume{$Volume}) { | |
146 | push @{$EXT4{$Volume}}, $errormsg if $EXT4{$Volume}; | |
147 | delete $EXT4Volume{$Volume} if ($errormsg =~ /recovery complete/); | |
148 | } | |
136 | 149 | } elsif ( ( my $errormsg ) = ( $ThisLine =~ /((BUG|WARNING|INFO):.{0,40})/ ) ) { |
137 | 150 | $Errors{$errormsg}++; |
151 | } elsif ( ( my $host ) = ( $ThisLine =~ /^nfs: server (.*) not responding/ ) ) { | |
152 | $NFS{$host}++; | |
138 | 153 | # OTHER |
139 | 154 | } else { |
140 | 155 | # XXX For now, going to ignore all other kernel messages as there |
156 | 171 | |
157 | 172 | if (keys %SYNflood) { |
158 | 173 | print "\nWarning: SYN flood on:\n"; |
159 | foreach my $ThisOne (sort {$a cmp $b} keys %SYNflood) { | |
160 | print " " . $ThisOne . " from:\n"; | |
161 | foreach my $Next (sort {$a cmp $b} keys %{$SYNflood{$ThisOne}}) { | |
162 | print " " . $Next . ": $SYNflood{$ThisOne}{$Next} Time(s)\n"; | |
174 | foreach my $Thisone (sort {$a cmp $b} keys %SYNflood) { | |
175 | print " " . $Thisone . " from:\n"; | |
176 | foreach my $Next (sort {$a cmp $b} keys %{$SYNflood{$Thisone}}) { | |
177 | print " " . $Next . ": $SYNflood{$Thisone}{$Next} Time(s)\n"; | |
163 | 178 | } |
164 | 179 | } |
165 | 180 | } |
185 | 200 | if (keys %SegFaults) { |
186 | 201 | my $header_printed=0; |
187 | 202 | foreach my $Thisone ( sort {$a cmp $b} keys %SegFaults ) { |
188 | if ($Ignore_faults =~ /\b\Q$Thisone\E\b/i) { next; } | |
203 | if ($Thisone =~ /^$Ignore_faults$/) { next; } | |
189 | 204 | if (!$header_printed) { |
190 | 205 | print "\nWARNING: Segmentation Faults in these executables\n"; |
191 | 206 | $header_printed=1; |
197 | 212 | if (keys %GPFaults) { |
198 | 213 | my $header_printed=0; |
199 | 214 | foreach my $Thisone ( sort {$a cmp $b} keys %GPFaults ) { |
200 | if ($Ignore_faults =~ /\b\Q$Thisone\E\b/i) { next; } | |
215 | if ($Thisone =~ /^$Ignore_faults$/) { next; } | |
201 | 216 | if (!$header_printed) { |
202 | 217 | print "\nWARNING: General Protection Faults in these executables\n"; |
203 | 218 | $header_printed=1; |
253 | 268 | } |
254 | 269 | } |
255 | 270 | |
271 | if (keys %NFS) { | |
272 | print "\nWARNING: NFS Sever Not Responding Messages\n"; | |
273 | foreach my $Thisone ( sort {$a cmp $b} keys %NFS ) { | |
274 | print " $Thisone ...: $NFS{$Thisone} Time(s)\n"; | |
275 | } | |
276 | } | |
277 | ||
278 | if (keys %EXT4) { | |
279 | print "\nWARNING: Ext4 Errors Present\n"; | |
280 | foreach my $Volume ( sort {$a cmp $b} keys %EXT4 ) { | |
281 | print " $Volume:\n"; | |
282 | foreach my $Msg (@{$EXT4{$Volume}}) { | |
283 | print " $Msg\n"; | |
284 | } | |
285 | } | |
286 | } | |
287 | ||
256 | 288 | # OTHER |
257 | 289 | if ( ($Detail >= 5) and (keys %Kernel) ) { |
258 | 290 | print "\n"; |
259 | foreach my $ThisOne (sort {$a cmp $b} keys %Kernel) { | |
260 | print $Kernel{$ThisOne} . " Time(s): " . $ThisOne . "\n"; | |
291 | foreach my $Thisone (sort {$a cmp $b} keys %Kernel) { | |
292 | print $Kernel{$Thisone} . " Time(s): " . $Thisone . "\n"; | |
261 | 293 | } |
262 | 294 | } |
263 | 295 |
17 | 17 | my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0; |
18 | 18 | my $PoolThreshold = $ENV{'pool_threshold'} || 0; |
19 | 19 | my $PoolMetadataThreshold = $ENV{'pool_metadata_threshold'} || 0; |
20 | my %Active; | |
20 | 21 | my %PoolUsed; |
21 | 22 | my %PoolMetadataUsed; |
22 | 23 | my $SnapshotThreshold = $ENV{'snapshot_threshold'} || 0; |
23 | 24 | my %SnapshotUsed; |
24 | 25 | my %MonitoringOn; |
25 | 26 | my %MonitoringOff; |
27 | my %MonitoringSnapshot; | |
26 | 28 | my %OtherList; |
27 | 29 | |
28 | 30 | while (defined(my $ThisLine = <STDIN>)) { |
29 | 31 | chomp($ThisLine); |
32 | # Seeing leading space on Fedora 26 | |
33 | $ThisLine =~ s/^ *//; | |
30 | 34 | if ($ThisLine =~ /^Thin (\S+) is now (\d+)% full/) { |
31 | 35 | $PoolUsed{$1} = $2 if $2 >= $PoolThreshold; |
32 | 36 | } elsif ($ThisLine =~ /^Thin metadata (\S+) is now (\d+)% full/) { |
33 | 37 | $PoolMetadataUsed{$1} = $2 if $2 >= $PoolMetadataThreshold; |
34 | } elsif ($ThisLine =~ /^Monitoring thin (\S+)\./) { | |
38 | } elsif ($ThisLine =~ /^Monitoring thin pool (\S+)\./) { | |
35 | 39 | $MonitoringOn{$1}++; |
36 | } elsif ($ThisLine =~ /^No longer monitoring thin (\S+)\./) { | |
40 | } elsif ($ThisLine =~ /^Monitoring snapshot (\S+)\./) { | |
41 | $MonitoringSnapshot{$1}++; | |
42 | } elsif ($ThisLine =~ /^No longer monitoring thin pool (\S+)\./) { | |
37 | 43 | $MonitoringOff{$1}++; |
38 | 44 | } elsif ($ThisLine =~ /^Snapshot (\S+) is now (\d+)% full/) { |
39 | 45 | $SnapshotUsed{$1} = $2 if $2 >= $SnapshotThreshold; |
46 | } elsif ($ThisLine =~ /^(\d+) logical volume\(s\) in volume group "(\S+)" monitored/) { | |
47 | $MonitoringOn{$2}++; | |
48 | } elsif ($ThisLine =~ /^(\d+) logical volume\(s\) in volume group "(\S+)" unmonitored/) { | |
49 | $MonitoringOff{$2}++; | |
50 | } elsif ($ThisLine =~ /^(\d+) logical volume\(s\) in volume group "(\S+)" now active/) { | |
51 | $Active{$2}=$1; | |
40 | 52 | } else { |
41 | 53 | $OtherList{$ThisLine}++; |
42 | 54 | } |
66 | 78 | print "\n"; |
67 | 79 | } |
68 | 80 | |
81 | if (keys %Active and $Detail) { | |
82 | print "LVM active:\n"; | |
83 | foreach my $VG (sort {$a cmp $b} keys %MonitoringOn) { | |
84 | print " $VG: $Active{$VG} logical volume(s)\n"; | |
85 | } | |
86 | print "\n"; | |
87 | } | |
88 | ||
69 | 89 | if (keys %MonitoringOn and $Detail) { |
70 | 90 | print "Monitoring started for:\n"; |
71 | 91 | foreach my $Pool (sort {$a cmp $b} keys %MonitoringOn) { |
78 | 98 | print "Monitoring stopped for:\n"; |
79 | 99 | foreach my $Pool (sort {$a cmp $b} keys %MonitoringOff) { |
80 | 100 | print " $Pool: $MonitoringOff{$Pool} Time(s)\n"; |
101 | } | |
102 | print "\n"; | |
103 | } | |
104 | ||
105 | if (keys %MonitoringSnapshot and $Detail) { | |
106 | print "Monitoring snapshot:\n"; | |
107 | foreach my $Snapshot (sort {$a cmp $b} keys %MonitoringSnapshot) { | |
108 | print " $Snapshot: $MonitoringSnapshot{$Snapshot} Time(s)\n"; | |
81 | 109 | } |
82 | 110 | print "\n"; |
83 | 111 | } |
5 | 5 | # This was written and is maintained by: |
6 | 6 | # Mike Tremaine <mgt \@\ stellarcore.net> |
7 | 7 | # |
8 | # Sophos Support and other improvments by Mark W. Nienberg | |
8 | # Sophos Support and other improvements by Mark W. Nienberg | |
9 | 9 | # MailScan_Spam_Act contributed by Kev Green |
10 | 10 | # |
11 | 11 | # Some more clean up rules based on extensive use of some MailScanner |
155 | 155 | $MailScan_Spam_Virus++; |
156 | 156 | $Spam_Virus_Found{$1}++; |
157 | 157 | } elsif ( $ThisLine =~ m/infected message .+ came from (.*)/i) { |
158 | $MailScan_VirualHost = $MailScan_VirualHost + 1; | |
158 | $MailScan_VirtualHost = $MailScan_VirtualHost + 1; | |
159 | 159 | $Hostlist{$1}++; |
160 | 160 | } elsif ( $ThisLine =~ m/Other Checks: Found ([0-9]+) problems/) { |
161 | 161 | $MailScan_Other = $MailScan_Other + $1; |
499 | 499 | } |
500 | 500 | |
501 | 501 | if (keys %Hostlist) { |
502 | print "\nVirus Sender Report: (Total Seen = $MailScan_VirualHost)\n"; | |
502 | print "\nVirus Sender Report: (Total Seen = $MailScan_VirtualHost)\n"; | |
503 | 503 | foreach $ThisOne (sort keys %Hostlist) { |
504 | 504 | print ' ' . $ThisOne . ': ' . $Hostlist{$ThisOne} . " Time(s)\n"; |
505 | 505 | } |
79 | 79 | } |
80 | 80 | |
81 | 81 | if (keys %NotFound) { |
82 | print "\nAttemts to mount nonexisting files or directories:\n"; | |
82 | print "\nAttempts to mount nonexisting files or directories:\n"; | |
83 | 83 | foreach $ThisOne (keys %NotFound) { |
84 | 84 | print " " . $ThisOne .":" . $NotFound{$ThisOne} . " Time(s)\n"; |
85 | 85 | } |
33 | 33 | Sep => 8, Oct => 9, Nov => 10, Dec => 11 ); |
34 | 34 | |
35 | 35 | # array of message categories (we do not use a hash to keep the order) |
36 | # first element: catorory name | |
36 | # first element: category name | |
37 | 37 | # second element: matching regexp ($1 should contain the message) |
38 | 38 | # third element: anonymous hash ref (stores message counts) |
39 | 39 | my @message_categories = (['Errors', qr/\[ERROR\] (.*)$/o, {}], |
72 | 72 | ($ThisLine =~ /recvfrom: No route to host/) or |
73 | 73 | # Be sure to catch: transfer of 'zone' from IP#53: failed to connect: timed out |
74 | 74 | # not exact just triggers a full transfer |
75 | ($ThisLine =~ /transfer of .*: (AXFR(|-style IXFR) (started|ended)|connected using|Transfer completed|failed while receiving responses: not exact)/) or | |
75 | ($ThisLine =~ /transfer of .*: (IXFR|AXFR(|-style IXFR) (started|ended)|connected using|Transfer completed|failed while receiving responses: not exact)/) or | |
76 | ($ThisLine =~ /Transfer status: success/) or | |
76 | 77 | ($ThisLine =~ /using \d+ CPU/) or |
77 | 78 | ($ThisLine =~ /loading configuration/) or |
78 | 79 | ($ThisLine =~ /command channel listening/) or |
80 | ($ThisLine =~ /configuring command channel from/) or | |
81 | ($ThisLine =~ /interface ignored/) or | |
79 | 82 | ($ThisLine =~ /no IPv6 interfaces found/) or |
83 | ($ThisLine =~ /using \d+ UDP listeners per interface/) or | |
80 | 84 | ($ThisLine =~ /^running/) or |
81 | 85 | ($ThisLine =~ /^exiting/) or |
82 | 86 | ($ThisLine =~ /no longer listening/) or |
109 | 113 | ($ThisLine =~ /open: .*: file not found/) or |
110 | 114 | ($ThisLine =~ /queries: client [\.0-9a-fA-F#:]* view localhost_resolver: query: .* IN .*/) or |
111 | 115 | ($ThisLine =~ /zone .*: NS '.*' is a CNAME \(illegal\)/) or |
116 | ($ThisLine =~ /skipping nameserver '.*' because it is a CNAME,/) or | |
112 | 117 | ($ThisLine =~ /zone .*: zone serial unchanged. zone may fail to transfer to slaves/) or |
113 | 118 | ($ThisLine =~ /zone .*: loading from master file .* failed/) or |
114 | 119 | ($ThisLine =~ /zone .*: NS '.*' has no address records/) or |
115 | 120 | ($ThisLine =~ /.*: not a valid number$/) or |
116 | ($ThisLine =~ /.*: unexpected end of input/) or | |
121 | ($ThisLine =~ /^(.*: )?unexpected end of input/) or | |
117 | 122 | ($ThisLine =~ /too many timeouts resolving '.*' .*: disabling EDNS/) or |
118 | 123 | ($ThisLine =~ /too many timeouts resolving '.*' .*: reducing the advertised EDNS UDP packet size to .* octets/) or |
119 | 124 | ($ThisLine =~ /reloading zones succeeded/) or |
135 | 140 | ($ThisLine =~ /^(error \()?broken trust chain\)? resolving '.*': .*/) or |
136 | 141 | ($ThisLine =~ /journal file [^ ]* does not exist, creating it/) or |
137 | 142 | ($ThisLine =~ /serial number \(\d+\) received from master/) or |
143 | ($ThisLine =~ /zone .*: notify from .*: serial \d+/) or | |
138 | 144 | ($ThisLine =~ /zone is up to date/) or |
139 | 145 | ($ThisLine =~ /refresh in progress, refresh check queued/) or |
140 | 146 | ($ThisLine =~ /refresh: NODATA response from master/) or |
142 | 148 | ($ThisLine =~ /reading built-in trusted keys from file/) or |
143 | 149 | ($ThisLine =~ /using built-in trusted-keys/) or |
144 | 150 | ($ThisLine =~ /set up managed keys zone/) or |
151 | ($ThisLine =~ /using .* as GeoIP directory/) or | |
152 | ($ThisLine =~ /GEO-.* Build/) or | |
153 | ($ThisLine =~ /initializing GeoIP /) or | |
145 | 154 | # the following seems okay since it says "success" |
146 | ($ThisLine =~ /managed-keys-zone .*: No DNSKEY RRSIGs found for '.*': success/) or | |
147 | ($ThisLine =~ /validating \@0x[[:xdigit:]]+: .* no valid signature found/) or | |
155 | ($ThisLine =~ /managed-keys-zone.*: No DNSKEY RRSIGs found for '.*': success/) or | |
156 | ($ThisLine =~ /managed-keys-zone.*: Unable to fetch DNSKEY set '.*': timed out/) or | |
148 | 157 | ($ThisLine =~ /^sizing zone task pool based on \d+ zones/) or |
149 | 158 | ($ThisLine =~ /^BIND \d+ is maintained by Internet Systems Consortium/) or |
150 | 159 | ($ThisLine =~ /a non-profit 501/) or |
157 | 166 | ($ThisLine =~ /reading built-in trusted keys from file/) or |
158 | 167 | ($ThisLine =~ /all zones loaded/) or |
159 | 168 | ($ThisLine =~ /client .* signer .* approved/) or |
169 | ($ThisLine =~ /stop limiting/) or | |
160 | 170 | # ignore this line because the following line describes the error |
161 | 171 | ($ThisLine =~ /unexpected error/) |
162 | 172 | ) { |
182 | 192 | $DeniedZoneTransfers{$Host}{$Zone}++; |
183 | 193 | } elsif ( ($Zone) = ( $ThisLine =~ /zone (.+) zone transfer deferred due to quota/ ) ) { |
184 | 194 | $DeferredZoneTransfers{$Zone}++; |
185 | } elsif ( ($Zone, $Host) = ( $ThisLine =~ /transfer of '(.+)' from ([^\#]+)#[^\:]+: failed/ ) ) { | |
195 | } elsif ( ($Zone, $Host) = ( $ThisLine =~ /transfer of '(.+)' from ([^\#]+)#[^\:]+: (failed|(Transfer status|giving up): ((network|host) unreachable|timed out|connection refused))/ ) ) { | |
186 | 196 | $FailedZoneTransfers{$Host}{$Zone}++; |
187 | 197 | } elsif ( ($Zone) = ( $ThisLine =~ /cache zone \"(.*)\" loaded/ ) ) { |
188 | 198 | $ZoneLoaded{"cache $Zone"}++; |
202 | 212 | $ZoneExpired{$Zone}++; |
203 | 213 | } elsif ( ($Zone) = ( $ThisLine =~ /zone (.+): loaded serial/ ) ) { |
204 | 214 | $ZoneLoaded{$Zone}++; |
215 | } elsif ( ($Zone) = ( $ThisLine =~ /(managed-keys-zone.*): loaded serial/ ) ) { | |
216 | $ZoneLoaded{$Zone}++; | |
205 | 217 | } elsif ( (undef,$Addr,$Server) = ( $ThisLine =~ /(C|c)onnection refused\)? resolving '(.+)': (.+)/ ) ) { |
206 | 218 | $ConnectionRefused{$Addr}{$Server}++; |
207 | 219 | } elsif ( (undef,$Addr,undef,$Server) = ( $ThisLine =~ /ame server (on|resolving) '(.+)' \(in .+\):\s+(\[.+\]\.\d+)?\s*'?(.+)'?:?/ ) ) { |
210 | 222 | (($Zone) = ( $ThisLine =~ /zone (.+): \(.*\) removed/ )) ) { |
211 | 223 | $ZoneRemoved{$Zone}++; |
212 | 224 | } elsif ( ($Zone) = ( $ThisLine =~ /received notify for zone '(.*)'/ ) ) { |
213 | $ZoneReceivedNotify{$Zone}++; | |
214 | } elsif ( ($Zone) = ( $ThisLine =~ /zone (.*): notify from .* up to date/ ) ) { | |
215 | 225 | $ZoneReceivedNotify{$Zone}++; |
216 | 226 | } elsif ( ($Zone) = ( $ThisLine =~ /zone (.+): refused notify from non-master/ ) ) { |
217 | 227 | $ZoneRefusedNotify{$Zone}++; |
238 | 248 | } elsif ( ($Client) = ( $ThisLine =~ /client (.*)#\d+: (?:view \w+: )?query \(cache\) denied/ ) ) { |
239 | 249 | $FullClient = LookupIP ($Client); |
240 | 250 | $DeniedQuery{$FullClient}++; |
241 | } elsif ( ($Client) = ( $ThisLine =~ /client (.*)#\d+: query '.*' denied/ ) ) { | |
251 | } elsif ( ($Client) = ( $ThisLine =~ /client (.*)(#\d+)?: query '.*' denied/ ) ) { | |
242 | 252 | $FullClient = LookupIP ($Client); |
243 | 253 | $DeniedQueryNoCache{$FullClient}++; |
244 | 254 | } elsif ( ($Rhost, $ViewName, $Ldom) = ($ThisLine =~ /client ([\.0-9a-fA-F:]+)#\d+: (?:view \w+: )?update '(.*)' denied/)) { |
250 | 260 | $InsecUpdate{$Zone}++; |
251 | 261 | } elsif ( ($Zone) = ($ThisLine =~ /zone ([0-9a-zA-Z.\/-]+): journal rollforward failed: journal out of sync with zone/)) { |
252 | 262 | $JournalFail{$Zone}++; |
263 | } elsif ( ($Zone) = ($ThisLine =~ /(managed-keys-zone.*): journal file is out of date: removing journal file/)) { | |
264 | $JournalFail{$Zone}++; | |
253 | 265 | } elsif ( ($Channel,$Reason) = ($ThisLine =~ /couldn't add command channel (.+#\d+): (.*)$/)) { |
254 | 266 | $ChannelAddFail{$Channel}{$Reason}++; |
255 | } elsif ( ($Zone,$Host,$Reason) = ($ThisLine =~ /zone ([^ ]*): refresh: failure trying master ([^ ]*)#\d+: (.*)/) ) { | |
267 | } elsif ( ($Zone,$Host,undef,$Reason) = ($ThisLine =~ /zone ([^ ]*): refresh: failure trying master ([^ ]*)#\d+( \(source .*\))?: (.*)/) ) { | |
256 | 268 | $MasterFailure{"$Zone from $Host"}{$Reason}++; |
257 | 269 | } elsif ( ($Zone,$Reason,$Host) = ($ThisLine =~ /zone ([^ ]*): refresh: unexpected rcode \((.*)\) from master ([^ ]*)#\d+/) ) { |
258 | 270 | $MasterFailure{"$Zone from $Host"}{$Reason}++; |
261 | 273 | } elsif ( ($Zone) = ($ThisLine =~ /zone ([^\/]+)\/.+: refresh: retry limit for master \S+ exceeded/) ) { |
262 | 274 | $RetryLimit{$Zone}++; |
263 | 275 | } elsif ( ($Rcode, $Zone, $Host) = ($ThisLine =~ /(?:error \()?unexpected RCODE\)? \(?(.*?)\)? resolving '(.*)': (.*)$/) ){ |
276 | $UnexpRCODE{$Rcode}{$Zone}{$Host}++; | |
277 | } elsif ( ($Rcode, $Zone, $Host) = ($ThisLine =~ /(.*) unexpected RCODE resolving '(.*)': (.*)$/) ){ | |
264 | 278 | $UnexpRCODE{$Rcode}{$Zone}{$Host}++; |
265 | 279 | } elsif ( ($ThisLine =~ /(?:error \()?FORMERR\)? resolving '[^ ]+: [.0-9a-fA-F:#]+/) or |
266 | 280 | ($ThisLine =~ /DNS format error from [^ ]+ resolving [^ ]+( for client [^ ]+)?: .*/) ) { |
276 | 290 | $ConfProb{$File}{"$Line,$Problem"}++; |
277 | 291 | } elsif ( (($ErrorText) = ($ThisLine =~ /^(RUNTIME_CHECK.*)/))or |
278 | 292 | (($ErrorText) = ($ThisLine =~ /^(.* REQUIRE.* failed.*)$/)) or |
279 | (($ErrorText) = ($ThisLine =~ /(.*: fatal error)/)) ) { | |
293 | (($ErrorText) = ($ThisLine =~ /(.*: fatal error)/)) or | |
294 | (($ErrorText) = ($ThisLine =~ /(.*: out of memory)/)) ) { | |
280 | 295 | $NError{$ErrorText}++; |
296 | } elsif ( (($ErrorText) = ($ThisLine =~ /^(GeoIP .* DB not available)/)) ) { | |
297 | $GeoIPError{$ErrorText}++; | |
281 | 298 | } elsif ( (($ErrorText) = ($ThisLine =~ /^(internal_accept: fcntl\(\) failed: Too many open files)/)) or |
282 | 299 | (($ErrorText) = ($ThisLine =~ /^(socket: too many open file descriptors)/)) ) { |
283 | 300 | $ErrOpenFiles{$ErrorText}++; |
298 | 315 | $NoSOA{$Client}++; |
299 | 316 | } elsif (($Hint) = ($ThisLine =~ /checkhints: (.*)/) ) { |
300 | 317 | $Hints{$Hint}++; |
318 | } elsif (($Response,$Net,$Zone) = ($ThisLine =~/limit (.+) responses to (\S+)(?: for (.+) \()?/)) { | |
319 | $Zone = "None" unless defined($Zone); | |
320 | $Limit{$Zone}{$Response}{$Net}++; | |
321 | } elsif (($Client,$Response,$Net,$Zone) = ($ThisLine =~/client ([^#]+)(?:#\d+)? \(.*\): (?:view \w+: )?rate limit drop (.+) response to (\S+)(?: for (\S+))?/)) { | |
322 | $Zone = "None" unless defined($Zone); | |
323 | $LimitDrop{$Zone}{$Response}{$Net}{$Client}++; | |
324 | } elsif (($Client,$Response,$Net,$Zone) = ($ThisLine =~/client ([^#]+)(?:#\d+)? \(.*\): (?:view \w+: )?rate limit slip (.+) response to (\S+)(?: for (\S+))?/)) { | |
325 | $Zone = "None" unless defined($Zone); | |
326 | $LimitSlip{$Zone}{$Response}{$Net}{$Client}++; | |
327 | } elsif (($Net,$Zone,$Response) = ($ThisLine =~/limit responses to (\S+)(?: for (\S+))? (.*) +\(/)) { | |
328 | $Zone = "None" unless defined($Zone); | |
329 | $Limit{$Zone}{$Response}{$Net}++; | |
330 | } elsif (($Client,$Net,$Zone,$Response) = ($ThisLine =~/client ([^#]+)(?:#\d+)? \(.*\): (?:view \w+: )?rate limit drop response to (\S+)(?: for (\S+))? (.*) +\(/)) { | |
331 | $Zone = "None" unless defined($Zone); | |
332 | $LimitDrop{$Zone}{$Response}{$Net}{$Client}++; | |
333 | } elsif (($Client,$Net,$Zone,$Response) = ($ThisLine =~/client ([^#]+)(?:#\d+)? \(.*\): (?:view \w+: )?rate limit slip response to (\S+)(?: for (\S+))? (.*) +\(/)) { | |
334 | $Zone = "None" unless defined($Zone); | |
335 | $LimitSlip{$Zone}{$Response}{$Net}{$Client}++; | |
301 | 336 | } elsif (($Zone,$RR) = ($ThisLine =~ /^\s*validating \@0x[[:xdigit:]]+: (.*) (\w+): got insecure response; parent indicates it should be secure/)) { |
302 | 337 | $DNSSECInsec{'__Total__'}++; |
303 | 338 | $DNSSECInsec{$Zone}{$RR}++; |
307 | 342 | } elsif (($Zone,$RR) = ($ThisLine =~ /^\s*validating \@0x[[:xdigit:]]+: (.*) (\w+): bad cache hit/)) { |
308 | 343 | $DNSSECBadCache{'__Total__'}++; |
309 | 344 | $DNSSECBadCache{$Zone}{$RR}++; |
310 | } elsif (($Error,$Host) = ($ThisLine =~ /error \((.*)\) resolving '([^']+)':/)) { | |
345 | } elsif (($Zone,$RR) = ($ThisLine =~ /^\s*validating \@0x[[:xdigit:]]+: (.*) (\w+): verify failed due to bad signature/)) { | |
346 | $DNSSECInvalid{'__Total__'}++; | |
347 | $DNSSECInvalid{$Zone}{$RR}++; | |
348 | } elsif (($Zone,$RR) = ($ThisLine =~ /^\s*validating ([^\/]*)\/(\w+): got insecure response; parent indicates it should be secure/)) { | |
349 | $DNSSECInsec{'__Total__'}++; | |
350 | $DNSSECInsec{$Zone}{$RR}++; | |
351 | } elsif (($Zone,$RR) = ($ThisLine =~ /^\s*validating ([^\/]*)\/(\w+): no valid signature found/)) { | |
352 | $DNSSECInvalid{'__Total__'}++; | |
353 | $DNSSECInvalid{$Zone}{$RR}++; | |
354 | } elsif (($Zone,$RR) = ($ThisLine =~ /^\s*validating ([^\/]*)\/(\w+): verify failed due to bad signature/)) { | |
355 | $DNSSECInvalid{'__Total__'}++; | |
356 | $DNSSECInvalid{$Zone}{$RR}++; | |
357 | } elsif (($Zone,$RR) = ($ThisLine =~ /^\s*validating ([^\/]*)\/(\w+): bad cache hit/)) { | |
358 | $DNSSECBadCache{'__Total__'}++; | |
359 | $DNSSECBadCache{$Zone}{$RR}++; | |
360 | } elsif (($Error,$Host) = ($ThisLine =~ /^(?:error \()?(.*)\)? resolving '([^']+)':/)) { | |
311 | 361 | $DNSSECError{$Error}{'__Total__'}++; |
312 | 362 | $DNSSECError{$Error}{$Host}++; |
313 | 363 | } elsif ($ThisLine =~ /^samba_dlz:/) { |
375 | 425 | } |
376 | 426 | |
377 | 427 | if ( keys %JournalFail ) { |
378 | print "\nJournall rollforward failed:\n"; | |
428 | print "\nJournal update failed:\n"; | |
379 | 429 | foreach $ThisOne (sort {$a cmp $b} keys %JournalFail) { |
380 | 430 | print " " . $ThisOne . ": " . $JournalFail{$ThisOne} . " Time(s)\n"; |
381 | 431 | } |
415 | 465 | } |
416 | 466 | } |
417 | 467 | |
468 | if (keys %Limit) { | |
469 | print "\nRate Limiting occurred for:\n"; | |
470 | foreach $Zone (keys %Limit) { | |
471 | print " $Zone:\n"; | |
472 | foreach $Response (keys %{$Limit{$Zone}}) { | |
473 | print " $Response:\n"; | |
474 | foreach $Net (keys %{$Limit{$Zone}{$Response}}) { | |
475 | print " $Net: $Limit{$Zone}{$Response}{$Net} Time(s)\n"; | |
476 | foreach $Client (keys %{$LimitDrop{$Zone}{$Response}{$Net}}) { | |
477 | print " Dropped $Client: $LimitDrop{$Zone}{$Response}{$Net}{$Client} Time(s)\n"; | |
478 | } | |
479 | foreach $Client (keys %{$LimitSlip{$Zone}{$Response}{$Net}}) { | |
480 | print " Slipped $Client: $LimitSlip{$Zone}{$Response}{$Net}{$Client} Time(s)\n"; | |
481 | } | |
482 | } | |
483 | } | |
484 | } | |
485 | } | |
486 | ||
487 | if ( ( $Detail >= 5 ) and (keys %GeoIPError) ) { | |
488 | print "\nGeoIP Errors:\n"; | |
489 | foreach $ThisOne (keys %GeoIPError) { | |
490 | print " " . $ThisOne . ": " . $GeoIPError{$ThisOne} . " Time(s)\n"; | |
491 | } | |
492 | } | |
493 | ||
418 | 494 | if ((keys %CCMessages) or (keys %CCMessages2)){ |
419 | 495 | print "\nMessages from control channel\n"; |
420 | 496 | foreach (keys %CCMessages) { |
637 | 713 | } |
638 | 714 | |
639 | 715 | if (($Detail >= 5) and (keys %UnexpRCODE)) { |
640 | print "\n Unexpected DNS RCODEs:\n"; | |
716 | print "\nUnexpected DNS RCODEs:\n"; | |
641 | 717 | foreach $ThisOne (sort {$a cmp $b} keys %UnexpRCODE) { |
642 | 718 | print " " . $ThisOne . ":\n"; |
643 | 719 | foreach $Zone (sort {$a cmp $b} keys %{$UnexpRCODE{$ThisOne}}) { |
650 | 726 | } |
651 | 727 | |
652 | 728 | if (($Detail >= 5) and (keys %FormErr)) { |
653 | print "\n Incorrect response format:\n"; | |
729 | print "\nIncorrect response format:\n"; | |
654 | 730 | foreach $ThisOne (keys %FormErr) { |
655 | 731 | print " " . $ThisOne . ": " . $FormErr{$ThisOne} . " Time(s)\n"; |
656 | 732 | } |
657 | 733 | } |
658 | 734 | |
659 | 735 | if (($Detail >= 10) and (keys %StartLog)) { |
660 | print "\n Named startup logs:\n"; | |
736 | print "\nNamed startup logs:\n"; | |
661 | 737 | foreach $ThisOne (keys %StartLog) { |
662 | 738 | print " " . $ThisOne . ": " . $StartLog{$ThisOne} . " Time(s)\n"; |
663 | 739 | } |
681 | 757 | } |
682 | 758 | |
683 | 759 | if (($Detail >= 5) and (keys %DNSSECInsec)) { |
684 | print "\n DNSSEC Insecure Responses: " . $DNSSECInsec{'__Total__'} . " Time(s)\n"; | |
760 | print "\nDNSSEC Insecure Responses: " . $DNSSECInsec{'__Total__'} . " Time(s)\n"; | |
685 | 761 | foreach $Zone (sort keys %DNSSECInsec) { |
686 | 762 | if (($Detail >= 10) and ($Zone =~ /.+/) and ($Zone ne '__Total__')) { |
687 | 763 | foreach $RR (sort keys %{$DNSSECInsec{$Zone}}) { |
692 | 768 | } |
693 | 769 | |
694 | 770 | if (($Detail >= 5) and (keys %DNSSECInvalid)) { |
695 | print "\n DNSSEC No Valid Signature: " . $DNSSECInvalid{'__Total__'} . " Time(s)\n"; | |
771 | print "\nDNSSEC No Valid Signature: " . $DNSSECInvalid{'__Total__'} . " Time(s)\n"; | |
696 | 772 | foreach $Zone (sort keys %DNSSECInvalid) { |
697 | 773 | if (($Detail >= 10) and ($Zone =~ /.+/) and ($Zone ne '__Total__')) { |
698 | 774 | foreach $RR (sort keys %{$DNSSECInvalid{$Zone}}) { |
703 | 779 | } |
704 | 780 | |
705 | 781 | if (($Detail >= 5) and (keys %DNSSECBadCache)) { |
706 | print "\n DNSSEC Bad Cache hit: " . $DNSSECBadCache{'__Total__'} . " Time(s)\n"; | |
782 | print "\nDNSSEC Bad Cache hit: " . $DNSSECBadCache{'__Total__'} . " Time(s)\n"; | |
707 | 783 | foreach $Zone (sort keys %DNSSECBadCache) { |
708 | 784 | if (($Detail >= 10) and ($Zone =~ /.+/) and ($Zone ne '__Total__')) { |
709 | 785 | foreach $RR (sort keys %{$DNSSECBadCache{$Zone}}) { |
714 | 790 | } |
715 | 791 | |
716 | 792 | if (($Detail >= 5) and (keys %DNSSECError)) { |
717 | print "\n DNS Errors:\n"; | |
793 | print "\nDNSSEC Errors:\n"; | |
718 | 794 | foreach $Error (sort keys %DNSSECError) { |
719 | 795 | print " $Error: " . $DNSSECError{$Error}{'__Total__'} . " Time(s)\n"; |
720 | 796 | if ($Detail >= 10) { |
406 | 406 | if ($Detail >= 15) { |
407 | 407 | |
408 | 408 | if (keys %InitAggMode) { |
409 | print "\nDevice initiating phase 1 aggresive mode:\n"; | |
409 | print "\nDevice initiating phase 1 aggressive mode:\n"; | |
410 | 410 | foreach $ThisOne (keys %InitAggMode) { |
411 | 411 | print " " . $ThisOne . ":\n"; |
412 | 412 | foreach $ThatOne (keys %{$InitAggMode{$ThisOne}}) { |
30 | 30 | } elsif (defined($Service)) { |
31 | 31 | # Skip informational messages if needed |
32 | 32 | next if (($Service == "Storage Service") and ($Message =~ /^The Patrol Read has (started|stopped)/) and ($Detail < 5)); |
33 | next if (($Service == "Storage Service") and ($Message =~ /^The controller battery Learn cycle will start in (?:\d+) days\./) and ($Detail < 5)); | |
33 | 34 | $ServiceMessage{$Service}->{$Message}++; |
34 | 35 | } else { |
35 | 36 | $OtherList{$ThisLine}++; |
26 | 26 | my $Debug = $ENV{'LOGWATCH_DEBUG'}; |
27 | 27 | my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'}; |
28 | 28 | my %Auth; |
29 | my $Config; | |
30 | my %ConfigValues; | |
29 | 31 | my %ConnErrors; |
30 | 32 | my %ConnectCauseDrop; |
31 | 33 | my %Connections; |
32 | 34 | my %Crypt; |
33 | 35 | my %Error; |
34 | 36 | my %IncorrectPassword; |
37 | my %ManagementCommands; | |
38 | my %ManagementConnections; | |
35 | 39 | my $MaxClients; |
36 | 40 | my $MaxConn; |
37 | 41 | my %OtherList; |
42 | my %PIDERRs; | |
38 | 43 | my %PluginCallFailure; |
39 | 44 | my %PluginCallOK; |
40 | 45 | my %VerifyList; |
41 | 46 | my %VersionInfo; |
47 | my %Warnings; | |
42 | 48 | |
43 | 49 | if ( $Debug >= 5 ) { |
44 | 50 | print STDERR "\n\nDEBUG \n\n"; |
46 | 52 | |
47 | 53 | while (defined(my $ThisLine = <STDIN>)) { |
48 | 54 | chomp($ThisLine); |
55 | ||
56 | if ($ThisLine =~ /^([\d]+\.[\d]+\.[\d]+\.[\d]+)\:([\d]+) TLS Auth Error: Auth Username\/Password verification failed for peer/) { | |
57 | $IncorrectPassword{$1}++; | |
58 | } | |
49 | 59 | |
50 | 60 | # normalise - this could possibly be used for more detailed per host statistics |
51 | 61 | # further down |
62 | 72 | ($ThisLine =~ /^Control Channel MTU parms/) or |
63 | 73 | ($ThisLine =~ /CRL CHECK OK: \/.*\//) or |
64 | 74 | ($ThisLine =~ /^Data Channel MTU parms/) or |
75 | ($ThisLine =~ /^Data Channel: using negotiated cipher/) or | |
65 | 76 | ($ThisLine =~ /^Delayed exit in \d+ seconds/) or |
66 | 77 | ($ThisLine =~ /^Diffie-Hellman initialized/) or |
67 | 78 | ($ThisLine =~ /^event_wait : Interrupted system call \(code=\d+\)/) or |
69 | 80 | ($ThisLine =~ /^Expected Remote Options/) or |
70 | 81 | ($ThisLine =~ /^GID set to/) or |
71 | 82 | ($ThisLine =~ /^IFCONFIG POOL/) or |
83 | ($ThisLine =~ /^ifconfig_pool_read/) or | |
84 | ($ThisLine =~ /^do_ifconfig/) or | |
85 | ($ThisLine =~ /^succeeded -> ifconfig_pool_set/) or | |
72 | 86 | ($ThisLine =~ /^IMPORTANT: OpenVPN's default port number is now 1194/) or |
73 | 87 | ($ThisLine =~ /^Initialization Sequence Completed/) or |
74 | 88 | ($ThisLine =~ /^Listening for incoming TCP connection on \S+:\d+/) or |
75 | ($ThisLine =~ /^LZO compression initialized/) or | |
76 | ($ThisLine =~ /^Local Options hash/) or | |
89 | ($ThisLine =~ /^LZO compression initializ/) or | |
90 | ($ThisLine =~ /^Local Options (hash|String)/) or | |
77 | 91 | ($ThisLine =~ /^MULTI: Learn:/) or |
78 | 92 | ($ThisLine =~ /^MULTI: multi_init called/) or |
79 | 93 | ($ThisLine =~ /^MULTI: multi_create_instance called/) or |
80 | 94 | ($ThisLine =~ /^MULTI: primary virtual IP for/) or |
95 | ($ThisLine =~ /^MULTI: primary virtual IPv6 for/) or | |
81 | 96 | ($ThisLine =~ /^MULTI: TCP INIT maxclients=\d+ maxevents=\d+/) or |
82 | 97 | ($ThisLine =~ /^MULTI: bad source address from client .*, packet dropped/) or |
83 | 98 | ($ThisLine =~ /^MULTI_sva: pool returned IPv4=/) or |
97 | 112 | ($ThisLine =~ /^send_push_reply/) or |
98 | 113 | ($ThisLine =~ /^SENT CONTROL/) or |
99 | 114 | ($ThisLine =~ /^SIGTERM\[hard,[^\]]*\] received, process exiting/) or |
115 | ($ThisLine =~ /^SIGTERM\[soft,[^\]]*\] received, client-instance exiting/) or | |
100 | 116 | ($ThisLine =~ /^SIGUSR1\[soft,(connection-reset|ping-restart)\] received, (process|client-instance) restarting/) or |
101 | 117 | ($ThisLine =~ /Socket Buffers: R=\[[0-9]+->[0-9]+\] S=\[[0-9]+->[0-9]+\]/) or |
102 | 118 | ($ThisLine =~ /^TCP\/UDP: Closing socket/) or |
103 | 119 | ($ThisLine =~ /^TCP\/UDP: Dynamic remote address changed during TCP connection establishment/) or |
120 | ($ThisLine =~ /^TCP\/UDP: Preserving recently used remote address: /) or | |
104 | 121 | ($ThisLine =~ /^TCP connection established with [\d.]+:\d+/) or |
105 | 122 | ($ThisLine =~ /^TCPv\d_(CLIENT|SERVER) link (local|remote)/) or |
106 | 123 | ($ThisLine =~ /^TLS-Auth MTU parms/) or |
113 | 130 | ($ThisLine =~ /^TLS: new session incoming connection from .*/) or |
114 | 131 | ($ThisLine =~ /TLS Error: TLS object -> incoming plaintext read error/) or |
115 | 132 | ($ThisLine =~ /TLS ERROR: received control packet with stale session-id=.*/) or |
116 | ($ThisLine =~ /^TUN\/TAP device \w+ opened/) or | |
133 | ($ThisLine =~ /^TUN\/TAP device \S+ opened/) or | |
117 | 134 | ($ThisLine =~ /TUN\/TAP TX queue length set to [0-9]*/) or |
135 | ($ThisLine =~ /^TUN\/TAP device \S+ exists previously, keep at program end/) or | |
118 | 136 | ($ThisLine =~ /^UDPv4 link /) or |
119 | 137 | ($ThisLine =~ /^UID set to/) or |
120 | 138 | ($ThisLine =~ /^VERIFY OK: nsCertType=\w+/) or |
139 | ($ThisLine =~ /^peer info: /) or | |
121 | 140 | ($ThisLine =~ /^chroot to /) or |
122 | 141 | ($ThisLine =~ /^LDAP bind failed: Invalid credentials$/) or |
123 | ($ThisLine =~ /Authenticate\/Decrypt packet error: bad packet ID \(may be a replay\): \[ #.* \] -- see the man page entry for --no-replay and --replay-window for more info or silence this warning with --mute-replay-warnings/) | |
142 | ($ThisLine =~ /^MANAGEMENT: Client disconnected$/) or | |
143 | ($ThisLine =~ /^MANAGEMENT: .* listening /) or | |
144 | ($ThisLine =~ /(?:AEAD Decrypt|Authenticate\/Decrypt packet) error: bad packet ID \(may be a replay\): \[ #.* \] -- see the man page entry for --no-replay and --replay-window for more info or silence this warning with --mute-replay-warnings/) | |
124 | 145 | ) { |
125 | 146 | # Don't care about these... |
126 | 147 | } elsif (my ($status, $depth, $dn) = ( $ThisLine =~ /^VERIFY (.*): depth=(.*), (.*)/ )) { |
136 | 157 | $VerifyList{"CRL check status: $status DN: $dn"}++; |
137 | 158 | } elsif ($ThisLine =~ /^TLS: Username\/Password authentication/) { |
138 | 159 | $VerifyList{$ThisLine}++; |
160 | } elsif ($ThisLine =~ /^user '.*' authenticated/) { | |
161 | # This will be handled by the above message | |
139 | 162 | } elsif ($ThisLine =~ /^Incorrect password supplied for .* "(.*)"/) { |
140 | 163 | $IncorrectPassword{$1}++; |
141 | 164 | } elsif ($ThisLine =~ m/^MULTI: new incoming connection would exceed maximum number of clients/) { |
142 | 165 | $MaxClients++; |
143 | 166 | } elsif ($ThisLine =~ m/^OpenVPN [\d.]+ [\w-]+ [\[\]\w ]+ built on [\w]+ +[\d]+ [\d]+$/) { |
167 | $VersionInfo{$ThisLine} = 1; | |
168 | } elsif ($ThisLine =~ m/^library versions: /) { | |
144 | 169 | $VersionInfo{$ThisLine} = 1; |
145 | 170 | } elsif (my ($config, $peer, $port) = ($ThisLine =~ m/^\[([\S]+)\] Peer Connection Initiated with [^\d]*([\d]+\.[\d]+\.[\d]+\.[\d]+)\:([\d]+)/)) { |
146 | 171 | push (@{$Connections{$config}{$peer}}, $port) unless grep(/^$port$/,@{$Connections{$config}{$peer}}); |
150 | 175 | $Auth{$channel}{$dir}{"$bits $algo"}++; |
151 | 176 | } elsif (my ($channel, $dir, $bits, $algo) = ($ThisLine =~ /^(Data Channel) (Encrypt|Decrypt): Using ([\d]+ bit) message hash '(\S+)' for HMAC authentication/)) { |
152 | 177 | $Auth{$channel}{$dir}{"$bits $algo"}++; |
153 | } elsif (my ($channel, $proto, $cipher) = ($ThisLine =~ /^(Control Channel): (\w+), cipher (.+)/)) { | |
178 | } elsif (my ($channel, $proto, $cipher) = ($ThisLine =~ /^(Control Channel): ([^,]+), cipher (.+)/)) { | |
154 | 179 | $Crypt{$channel}{$proto}{$cipher}++; |
155 | 180 | } elsif (my ($channel, $dir, $algo, $bits) = ($ThisLine =~ /^(Data Channel) (Encrypt|Decrypt): Cipher '(\S+)' initialized with ([\d]+ bit) key/)) { |
181 | $Crypt{$channel}{$dir}{"$bits $algo"}++; | |
182 | } elsif (my ($dir, $channel, $algo, $bits) = ($ThisLine =~ /^(Incoming|Outgoing) (Data Channel): Cipher '(\S+)' initialized with ([\d]+ bit) key/)) { | |
156 | 183 | $Crypt{$channel}{$dir}{"$bits $algo"}++; |
157 | 184 | } elsif (my ($proto, $host, $port, $error) = ($ThisLine =~ /^(TCP|UDP): connect to ([\d.]+):(\d+) failed, will try again in \d+ seconds: (.*)/)) { |
158 | 185 | $ConnErrors{$error}{"$proto $host:$port"}++; |
160 | 187 | $ConnErrors{$error}{"$proto"}++; |
161 | 188 | } elsif (my ($name) = ($ThisLine =~ /MULTI: new connection by client '(.*)' will cause previous active sessions by this client to be dropped. Remember to use the --duplicate-cn option if you want multiple clients using the same certificate or username to concurrently connect./)) { |
162 | 189 | $ConnectCauseDrop{$name}++; |
190 | } elsif (my ($Command) = ($ThisLine =~ /^MANAGEMENT: CMD '(.*)'/)) { | |
191 | $ManagementCommands{$Command}++; | |
192 | } elsif (my ($Connection) = ($ThisLine =~ /^MANAGEMENT: Client connected from (.*)/)) { | |
193 | $ManagementConnections{$Connection}++; | |
163 | 194 | } elsif ((my ($Err) = ($ThisLine =~ /(read UDPv4 \[ECONNREFUSED\]: Connection refused \(code=111\))/)) or |
164 | 195 | (my ($Err) = ($ThisLine =~ /(read UDPv4 \[EHOSTUNREACH\]: No route to host \(code=113\))/))) { |
165 | 196 | $Error{$Err}++; |
197 | } elsif (my ($PIDERR) = ($ThisLine =~ /^PID_ERR ([^[]+) \[/)) { | |
198 | $PIDERRs{$PIDERR}++; | |
199 | } elsif (my ($Warning) = ($ThisLine =~ /^WARNING: (.*)/)) { | |
200 | $Warnings{$Warning}++; | |
166 | 201 | } elsif (my ($plugin,$call,$status) = ($ThisLine =~ /^PLUGIN_CALL: POST (.*)\/(PLUGIN_.*) status=(.*)/)) { |
167 | 202 | if ($status == 0) { |
168 | 203 | $PluginCallOK{$plugin}{$call}++; |
169 | 204 | } else { |
170 | 205 | $PluginCallFailure{$plugin}{$call}++; |
171 | 206 | } |
207 | } elsif ($ThisLine =~ /(Current Parameter Settings|Connection profiles \[.*\]):$/) { | |
208 | $Config = $1; | |
209 | } elsif ($ThisLine =~ /Connection profiles END$/) { | |
210 | $Config = ""; | |
211 | } elsif (my ($ConfigValue) = ($ThisLine =~ /^ (.*)/)) { | |
212 | $ConfigValues{$Config}->{$ConfigValue} = 1; | |
172 | 213 | } else { |
173 | 214 | # Report any unmatched entries... |
174 | 215 | # remove PID from named messages |
180 | 221 | |
181 | 222 | ################################################ |
182 | 223 | |
224 | ||
225 | if (keys %Warnings) { | |
226 | print "\nWARNINGS:\n"; | |
227 | foreach my $Warning (sort keys %Warnings) { | |
228 | print " " . $Warning . ": " .$Warnings{$Warning}. " Time(s)\n"; | |
229 | } | |
230 | } | |
231 | ||
232 | if (keys %PIDERRs) { | |
233 | print "\nPID_ERRs:\n"; | |
234 | foreach my $PIDERR (sort keys %PIDERRs) { | |
235 | print " " . $PIDERR . ": " .$PIDERRs{$PIDERR}. " Time(s)\n"; | |
236 | } | |
237 | } | |
183 | 238 | |
184 | 239 | if(keys %ConnErrors) { |
185 | 240 | print "Connection Errors:\n"; |
298 | 353 | } |
299 | 354 | } |
300 | 355 | |
356 | if (keys %ManagementConnections and $Detail) { | |
357 | print "\nManagement Connections from:\n"; | |
358 | foreach my $Connection (sort keys %ManagementConnections) { | |
359 | print " " . $Connection . ": " .$ManagementConnections{$Connection}. " Time(s)\n"; | |
360 | } | |
361 | } | |
362 | ||
363 | if (keys %ManagementCommands and $Detail) { | |
364 | print "\nManagement Commands:\n"; | |
365 | foreach my $Command (sort keys %ManagementCommands) { | |
366 | print " " . $Command . ": " .$ManagementCommands{$Command}. " Time(s)\n"; | |
367 | } | |
368 | } | |
369 | ||
370 | if (keys %ConfigValues and $Detail >= 10) { | |
371 | foreach my $config (sort keys %ConfigValues) { | |
372 | print "\n$config:"; | |
373 | foreach my $configvalue (sort keys %{$ConfigValues{$config}}) { | |
374 | print "\n $configvalue"; | |
375 | } | |
376 | print "\n"; | |
377 | } | |
378 | } | |
379 | ||
301 | 380 | if (keys %OtherList) { |
302 | 381 | print "\n**Unmatched Entries**\n"; |
303 | 382 | foreach my $line (sort {$a cmp $b} keys %OtherList) { |
162 | 162 | } |
163 | 163 | #lowercase the service |
164 | 164 | $service = lc($service); |
165 | if ( grep $_ eq $service, qw/ssh sshd login ftp vsftpd proftpd rsh remote rlogin rexec/) { | |
165 | if ( grep $_ eq $service, qw/ssh sshd login ftp vsftpd proftpd rsh remote rlogin rexec systemd-user/) { | |
166 | 166 | if ($line =~ s/^session opened for user (.+) by \(uid=\d+\)/$1/) { |
167 | 167 | ($Detail >= 5) && $data{$service}{'Sessions Opened'}{$line}++; |
168 | 168 | } elsif ($line =~ s/^session opened for user ([^ ]*) by ([^ ]*)\(uid=\d+\)/$1 by $2/) { |
188 | 188 | $data{$service}{'Invalid Users'}{'Unknown Account'}++; |
189 | 189 | } elsif ($line =~ s/^password changed for (.+)/$1(by sshd)/) { |
190 | 190 | ($Detail >= 5) && $data{passwd}{'Password changed'}{$line}++; |
191 | } elsif ($line =~ s/^account (.+) has expired (failed to change password)$/$1/) { | |
191 | } elsif ($line =~ s/^account (.+) has expired \((?:failed to change password|account expired)\)$/$1/) { | |
192 | 192 | $data{$service}{'Expired Accounts'}{$line}++; |
193 | 193 | } elsif ($line =~ s/bad username \[(.*)\]/$1/) { |
194 | 194 | $data{$service}{'Invalid Users'}{"Bad User: $line"}++; |
197 | 197 | } else { |
198 | 198 | $data{$service}{'Unknown Entries'}{$line}++; |
199 | 199 | } |
200 | } elsif (grep $_ eq $service, qw/su sudo su-l/) { | |
200 | } elsif (grep $_ eq $service, qw/su sudo su-l polkit-1/) { | |
201 | 201 | if ( my ($logname, $uid, $ruser, $user) = ($line =~ /^authentication failure; logname=(\S*)\s+uid=(\d+) (?:.*ruser=(\S*)\s+)?.*user=(\S*)$/)) { |
202 | 202 | $line = ($logname or $ruser)."($uid) -> $user"; |
203 | 203 | $data{$service}{'Authentication Failures'}{$line}++; |
227 | 227 | if ($line =~ s/^password changed for (.+)/$1/) { |
228 | 228 | ($Detail >= 5) && $data{$service}{'Password changed'}{$line}++; |
229 | 229 | } |
230 | } elsif (grep $_ eq $service, qw/gdm gdm-password gdm-welcome kdm kcheckpass xdm imap dovecot cups/) { | |
231 | if ($line =~ s/^session opened for user (.+) by (?:\(unknown\))?\(uid=\d+\)/$1/) { | |
230 | } elsif (grep $_ eq $service, qw/gdm gdm-password gdm-welcome gdm-launch-environment kdm kcheckpass xdm imap dovecot cups/) { | |
231 | if ($line =~ s/^session opened for user (.+) by (?:\(unknown\)|\w+)?\(uid=\d+\)/$1/) { | |
232 | 232 | ($Detail >= 5) && $data{$service}{'Sessions Opened'}{$line}++; |
233 | 233 | } elsif ($line =~ s/^authentication failure;.* user=(.+)$/$1/) { |
234 | 234 | $data{$service}{'Authentication Failures'}{$line}++; |
45 | 45 | Sep => 8, Oct => 9, Nov => 10, Dec => 11 ); |
46 | 46 | |
47 | 47 | # array of message categories (we do not use a hash to keep the order) |
48 | # first element: catorory name | |
48 | # first element: category name | |
49 | 49 | # second element: matching regexp ($1 should contain the message) |
50 | 50 | # third element: anonymous hash ref (stores message counts) |
51 | 51 | my @message_categories = (['Fatal errors', qr/\] PHP Fatal error: (.*)$/o, {}], |
62 | 62 | my $line = $_; |
63 | 63 | # skipping messages that are not within the requested range |
64 | 64 | # the last part of the regex matches optionally occurring specification |
65 | # of timezones, either in Continent/City or abbrevations like UTC | |
65 | # of timezones, either in Continent/City or abbreviations like UTC | |
66 | 66 | next unless $line =~ /^\[($filter)(?: \w+(?:\/\w+)?)?\]/o; |
67 | 67 | $1 =~ /(\d+)-(\w+)-(\d+) (\d+):(\d+):(\d+)/; |
68 | 68 | my $time; |
45 | 45 | # Please CC suggestions to mcr@freeswan.org and/or design@lists.freeswan.org |
46 | 46 | |
47 | 47 | # the vendorID hash maps vendor IDs to products. VendorIDs are hashs of |
48 | # internal stuff from each vendor. Grow this table as you encouter new | |
48 | # internal stuff from each vendor. Grow this table as you encounter new | |
49 | 49 | # products. |
50 | 50 | |
51 | 51 | ####################################################### |
176 | 176 | #$MboxSize{$User} = $LeftSize; |
177 | 177 | } elsif ( ($Host,$Iface) = ( $ThisLine =~ /^listeners_post_select: client \[\d\](.*)\/.*: connected to local address (.*:\d+)$/ ) ) { |
178 | 178 | $Connection{$Host}++; |
179 | $Conect{$Iface}{$Host}++; | |
179 | $Connect{$Iface}{$Host}++; | |
180 | 180 | } elsif ( ($Listen) = ( $ThisLine =~ /^parse_listeners: listening on address (.*)$/ ) ) { |
181 | 181 | $ListenOn{$Listen}++; |
182 | 182 | } elsif ($ThisLine =~ /^net_loop: tpop3d version \d+\.\d+\.\d+ successfully started$/ ) { |
375 | 375 | print "Socket Write Error $WriteSocketError Time(s)\n"; |
376 | 376 | } |
377 | 377 | |
378 | if (keys %Conect) { | |
378 | if (keys %Connect) { | |
379 | 379 | print "\nConnection to interface:\n"; |
380 | foreach $Iface (sort {$a cmp $b} keys %Conect) { | |
380 | foreach $Iface (sort {$a cmp $b} keys %Connect) { | |
381 | 381 | print " $Iface:\n"; |
382 | foreach $Host (sort {$a cmp $b} keys %{$Conect{$Iface}}) { | |
383 | print " $Host: $Conect{$Iface}{$Host} Time(s)\n"; | |
382 | foreach $Host (sort {$a cmp $b} keys %{$Connect{$Iface}}) { | |
383 | print " $Host: $Connect{$Iface}{$Host} Time(s)\n"; | |
384 | 384 | } |
385 | 385 | } |
386 | 386 | } |
138 | 138 | } |
139 | 139 | |
140 | 140 | if ( ($Detail >= 5) and (keys %Unknown) ) { |
141 | print "\n**Unmached entries**\n"; | |
141 | print "\n**Unmatched entries**\n"; | |
142 | 142 | foreach $ThisOne (sort {$a cmp $b} keys %Unknown) { |
143 | 143 | print $Unknown{$ThisOne} . " Time(s): " . $ThisOne . "\n"; |
144 | 144 | } |
635 | 635 | my $pass_through = shift; |
636 | 636 | #$SIG{__WARN__} = sub { print "*** $_[0]*** options error\n" }; |
637 | 637 | # ensure we're called after %Opts is initialized |
638 | die "get_options: program error: %Opts is emtpy" unless exists $Opts{'debug'}; | |
638 | die "get_options: program error: %Opts is empty" unless exists $Opts{'debug'}; | |
639 | 639 | |
640 | 640 | my $p = new Getopt::Long::Parser; |
641 | 641 | |
1014 | 1014 | |
1015 | 1015 | a = show level a detail |
1016 | 1016 | b = show at most b items at this level |
1017 | c = minimun count that will be shown | |
1017 | c = minimum count that will be shown | |
1018 | 1018 | =cut |
1019 | 1019 | |
1020 | 1020 | sub printTree($ $ $ $ $) { |
1115 | 1115 | # TOTAL: an integer: which is the subtotal of this item's children |
1116 | 1116 | # LEVEL: an integer > 0: representing this entry's level in the tree |
1117 | 1117 | # CHILDREF: a listref: references a list consisting of this node's children |
1118 | # Total: The cummulative total of items found for a given invocation | |
1118 | # Total: The cumulative total of items found for a given invocation | |
1119 | 1119 | # |
1120 | 1120 | # Use the special key variable $END_KEY, which is "\a\a" (two ASCII bell's) to end a, |
1121 | 1121 | # nested hash early, or the empty string '' may be used as the last key. |
1359 | 1359 | my ($numfmt, $desc, $divisor) = ($sref->{FMT}, $sref->{TITLE}, $sref->{DIVISOR}); |
1360 | 1360 | |
1361 | 1361 | my $fmt = '%8'; |
1362 | my $extra = ' %25s'; | |
1362 | my $extra = ' %11s'; | |
1363 | 1363 | my $total = $Totals{$keyname}; |
1364 | 1364 | |
1365 | 1365 | # Z format provides unitized or unaltered totals, as appropriate |
1382 | 1382 | } |
1383 | 1383 | else { |
1384 | 1384 | push @{$lines[$cur_level]}, |
1385 | sprintf "$fmt %-23s $extra\n", $total, $desc, commify ($Totals{$keyname}); | |
1385 | sprintf "$fmt %-37s $extra\n", $total, $desc, commify ($Totals{$keyname}); | |
1386 | 1386 | } |
1387 | 1387 | } |
1388 | 1388 | } |
2468 | 2468 | } |
2469 | 2469 | } |
2470 | 2470 | elsif ($line =~ /^err/) { |
2471 | # coerrce policyd-weight err's into general warnings | |
2471 | # coerce policyd-weight err's into general warnings | |
2472 | 2472 | $Totals{'startuperror'}++; |
2473 | 2473 | $Counts{'startuperror'}{'Service: policyd-weight'}{$line}++ if ($Logreporters::TreeData::Collecting{'startuperror'}); |
2474 | 2474 | return; |
2574 | 2574 | to group rejects to R1, [R2 ...], |
2575 | 2575 | where patterns are [45][.0-9][.0-9] |
2576 | 2576 | or "Warn" (default: 5.. 4.. Warn) |
2577 | Supplimental reports | |
2577 | Supplemental reports | |
2578 | 2578 | --[no]delays [do not] show msg delays percentiles report |
2579 | 2579 | --delays_percentiles "P1 [P2 ...]" set delays report percentiles to |
2580 | 2580 | P1 [P2 ...] (range: 0...100) |
2617 | 2617 | my @ignore_list = (); |
2618 | 2618 | |
2619 | 2619 | # The Sections table drives Summary and Detail reports. For each entry in the |
2620 | # table, if there is data avaialable, a line will be output in the Summary report. | |
2620 | # table, if there is data available, a line will be output in the Summary report. | |
2621 | 2621 | # Additionally, a sub-section will be output in the Detail report if both the |
2622 | 2622 | # global --detail, and the section's limiter variable, are sufficiently high (a |
2623 | 2623 | # non-existent section limiter variable is considered to be sufficiently high). |
3268 | 3268 | $SizeByQid{$qid} = $bytes; |
3269 | 3269 | # ...but only when the smtpd "client=..." line has been seen too. |
3270 | 3270 | # This under-counts when the smtpd "client=..." connection log entry and the |
3271 | # qmgr "from=..." log entry span differnt periods (as fed to postfix-logwatch). | |
3271 | # qmgr "from=..." log entry span different periods (as fed to postfix-logwatch). | |
3272 | 3272 | next if (! exists $AcceptedByQid{$qid}); |
3273 | 3273 | |
3274 | 3274 | $Totals{'bytesaccepted'} += $bytes; |
3691 | 3691 | $Totals{'totalacceptplusreject'} = $Totals{'msgsaccepted'} + $Totals{'totalrejects'}; |
3692 | 3692 | |
3693 | 3693 | # Print the Summary report if any key has non-zero data. |
3694 | # Note: must explicitely check for any non-zero data, | |
3694 | # Note: must explicitly check for any non-zero data, | |
3695 | 3695 | # as Totals always has some keys extant. |
3696 | 3696 | # |
3697 | 3697 | if ($Opts{'summary'}) { |
4609 | 4609 | } elsif ($warning =~ /^(Unable to look up \S+ host) (.+)$/) { |
4610 | 4610 | #TDsd warning: Unable to look up MX host for example.com: Host not found |
4611 | 4611 | #TDsd warning: Unable to look up MX host mail.example.com for Sender address from@example.com: hostname nor servname provided, or not known |
4612 | #TDsd warning: Unable to look up NS host ns1.example.logal for Sender address bounce@example.local: No address associated with hostname | |
4612 | #TDsd warning: Unable to look up NS host ns1.example.local for Sender address bounce@example.local: No address associated with hostname | |
4613 | 4613 | $Totals{'dnserror'}++; return unless ($Collecting{'dnserror'}); |
4614 | 4614 | |
4615 | 4615 | my ($problem,$target,$reason) = ($1, split(/: /,$2)); |
5221 | 5221 | # these take affect if no env present (eg. nothing in conf file) |
5222 | 5222 | # 0 to 4 nodelays |
5223 | 5223 | |
5224 | if ($Opts{'detail'} < 5) { # detail 0 to 4, disable all supplimental reports | |
5224 | if ($Opts{'detail'} < 5) { # detail 0 to 4, disable all supplemental reports | |
5225 | 5225 | $Opts{'delays'} = 0; |
5226 | 5226 | $Opts{'postgrey_delays'} = 0; |
5227 | 5227 | } |
5256 | 5256 | # don't reorder the list of limiters. This breaks --nodetail followed by a |
5257 | 5257 | # bare reject such as --limit rejectrbl=10. Reordering is no longer necessary |
5258 | 5258 | # since process_limiters was instituted and using the special __none__ pseudo- |
5259 | # limiter to indicate the position at which --nodefailt was found on the command | |
5259 | # limiter to indicate the position at which --nodetail was found on the command | |
5260 | 5260 | # line. |
5261 | 5261 | # my ($limiter, @reject_limiters, @non_reject_limiters); |
5262 | 5262 | my ($limiter, @new_list); |
16 | 16 | # |
17 | 17 | # Revision 1.8 2005/07/21 05:49:21 bjorn |
18 | 18 | # Allows for spaces in filenames; adds transfer statistics; |
19 | # ignores deleted/moved/renamed files. Patches from Piotr Krukowieck. | |
19 | # ignores deleted/moved/renamed files. Patches from Piotr Krukowiecki. | |
20 | 20 | # |
21 | 21 | # Revision 1.7 2005/07/13 16:07:53 mike |
22 | 22 | # Fixed ignoreunmatched typo and set env variable for it -mgt |
155 | 155 | } |
156 | 156 | } |
157 | 157 | |
158 | if (($#OtherList >= 0) and (not $IngoreUnmatched)){ | |
158 | if (($#OtherList >= 0) and (not $IgnoreUnmatched)){ | |
159 | 159 | print "\n**Unmatched Entries**\n"; |
160 | 160 | print @OtherList; |
161 | 161 | } |
138 | 138 | } |
139 | 139 | } |
140 | 140 | |
141 | if (($#OtherList >= 0) and (not $IngoreUnmatched)){ | |
141 | if (($#OtherList >= 0) and (not $IgnoreUnmatched)){ | |
142 | 142 | print "\n**Unmatched Entries**\n"; |
143 | 143 | print @OtherList; |
144 | 144 | } |
468 | 468 | print "$ct times\n"; |
469 | 469 | } |
470 | 470 | |
471 | if (($#OtherList >= 0) and (not $IngoreUnmatched)) | |
471 | if (($#OtherList >= 0) and (not $IgnoreUnmatched)) | |
472 | 472 | { |
473 | 473 | print "\n**Unmatched Entries**\n"; |
474 | 474 | print @OtherList; |
39 | 39 | # These scripts were created as part of the dnssec-tools project. |
40 | 40 | # For more information, see http://sourceforge.net/dnssec-tools. |
41 | 41 | # Detailed instructions for setting up BIND 9.3.* to use these logwatch |
42 | # configuration files and scripts are containted in the README file | |
42 | # configuration files and scripts are contained in the README file | |
43 | 43 | # on sourceforge. |
44 | 44 | ############################################################################# |
45 | 45 |
20 | 20 | ######################################################### |
21 | 21 | |
22 | 22 | my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0; |
23 | my %IgnoreActions; | |
24 | if (defined($ENV{'rsyslogd_ignore_actions'})) { | |
25 | foreach my $action (split(";",$ENV{'rsyslogd_ignore_actions'})) { | |
26 | $IgnoreActions{$action} = 1; | |
27 | } | |
28 | } | |
29 | my %IgnoreMessages; | |
30 | if (defined($ENV{'rsyslogd_ignore_messages'})) { | |
31 | foreach my $message (split(";",$ENV{'rsyslogd_ignore_messages'})) { | |
32 | $IgnoreMessages{$message} = 1; | |
33 | } | |
34 | } | |
35 | my %IgnoreModules; | |
36 | if (defined($ENV{'rsyslogd_ignore_modules'})) { | |
37 | foreach my $module (split(";",$ENV{'rsyslogd_ignore_modules'})) { | |
38 | $IgnoreModules{$module} = 1; | |
39 | } | |
40 | } | |
41 | my $Message; | |
42 | my $Reason; | |
43 | my %ActionResumed; | |
44 | my %ActionSuspended; | |
45 | my %DaemonActions; | |
23 | 46 | |
47 | LINE: | |
24 | 48 | while (defined($ThisLine = <STDIN>)) { |
25 | 49 | chomp($ThisLine); |
26 | if ($ThisLine =~ /^.*] start$/) { | |
27 | $Starts++; | |
50 | foreach $Message (%IgnoreMessages) { | |
51 | next LINE if $ThisLine =~ /$Message/i; | |
28 | 52 | } |
29 | elsif ($ThisLine =~ /^.*rsyslogd was HUPed$/) { | |
30 | $HUPs++; | |
53 | if (($Reason) = ($ThisLine =~ /^ ?\[origin software=\"rsyslogd\" .*\] (.*)/)) { | |
54 | $DaemonActions{$Reason}++; | |
55 | } | |
56 | elsif (my ($Action, $Module) = $ThisLine =~ /action '(.*)' suspended(?: \(module '(.*)'\))?/) { | |
57 | if (defined $Module) { | |
58 | $ActionSuspended{"$Action ($Module)"}++ unless defined $IgnoreActions{$Action} or defined $IgnoreModules{$Module}; | |
59 | } else { | |
60 | $ActionSuspended{$Action}++ unless defined $IgnoreActions{$Action}; | |
61 | } | |
62 | } | |
63 | elsif (my ($Action, $Module) = $ThisLine =~ /action '(.*)' resumed \(module '(.*)'\)/) { | |
64 | $ActionResumed{"$Action ($Module)"}++ unless defined $IgnoreActions{$Action} or defined $IgnoreModules{$Module}; | |
65 | } | |
66 | elsif ( | |
67 | $ThisLine =~ /^rsyslogd\'s (groupid|userid) changed to/ or | |
68 | $ThisLine =~ /^imjournal: journal reloaded/ or | |
69 | $ThisLine =~ /^message repeated \d+ times:/ or | |
70 | 0 # This line prevents blame shifting as lines are added above | |
71 | ) { | |
72 | # Ignore these lines | |
31 | 73 | } |
32 | 74 | else { |
33 | 75 | # Report any unmatched entries... |
35 | 77 | } |
36 | 78 | } |
37 | 79 | |
38 | if ($Starts and ($Detail >=10) ) { | |
39 | print "\nrsyslogd started " . $Starts . " Time(s)\n"; | |
80 | if (keys %ActionSuspended) { | |
81 | print "Rsyslogd actions suspended:\n"; | |
82 | foreach my $Action (sort keys %ActionSuspended) { | |
83 | print " $Action: $ActionSuspended{$Action} Times\n"; | |
84 | } | |
85 | print "\n"; | |
40 | 86 | } |
41 | 87 | |
42 | if ($HUPs and ($Detail >=10) ) { | |
43 | print "\nrsyslogd closed files " . $HUPs. " Time(s)\n"; | |
88 | if (keys %ActionResumed) { | |
89 | print "Rsyslogd actions resumed\n"; | |
90 | foreach my $Action (sort keys %ActionResumed) { | |
91 | print " $Action: $ActionResumed{$Action} Times\n"; | |
92 | } | |
93 | print "\n"; | |
94 | } | |
95 | ||
96 | if (($Detail >=10) and (keys %DaemonActions) ) { | |
97 | print "Rsyslogd Actions:\n"; | |
98 | foreach $Reason (sort keys %DaemonActions) { | |
99 | print " $Reason: $DaemonActions{$Reason} Times\n"; | |
100 | } | |
101 | print "\n"; | |
44 | 102 | } |
45 | 103 | |
46 | 104 | if (keys %OtherList) { |
47 | print "\n**** Unmatched entries ****\n"; | |
105 | print "**** Unmatched entries ****\n"; | |
48 | 106 | foreach $Error (keys %OtherList) { |
49 | 107 | print " $Error : $OtherList{$Error} Times\n"; |
50 | 108 | } |
36 | 36 | # Removed ignore for connect -mgt |
37 | 37 | # |
38 | 38 | # Revision 1.7 2005/02/21 03:28:44 mgt |
39 | # Added patch from Anssi Kolehmained for host connections -mgt | |
39 | # Added patch from Anssi Kolehmainen for host connections -mgt | |
40 | 40 | # |
41 | 41 | # Revision 1.6 2005/02/16 00:43:28 mgt |
42 | 42 | # Added #vi tag to everything, updated ignore.conf with comments, added emerge and netopia to the tree from Laurent -mgt |
242 | 242 | } elsif ( $ThisLine =~ m/reload_interfaces: No subnets to listen to. Shutting down.../) { |
243 | 243 | $SubnetFail{"No subnets to listen to. Shutting down."}++; |
244 | 244 | } elsif ( $ThisLine =~ s/process_get_backup_list_request\([0-9]+\) process_get_backup_list_request: (.*)/$1/) { |
245 | $GetBacupList{$ThisLine}++; | |
245 | $GetBackupList{$ThisLine}++; | |
246 | 246 | } elsif ( ($Error) = ($ThisLine =~ /brl_init\([0-9]+\) (Failed to open byte range locking database)$/)) { |
247 | 247 | $LockDbError{$Error}++; |
248 | 248 | } elsif ( ($Error) = ($ThisLine =~ /locking_init\([0-9]+\) ERROR: (Failed to initialise locking database)$/)) { |
368 | 368 | if (keys %CrFile) { |
369 | 369 | print "\nCreated files\n"; |
370 | 370 | foreach $Line (keys %CrFile) { |
371 | print " file $Line did not exist. File succesfully created: $CrFile{$Line} Time(s)\n"; | |
371 | print " file $Line did not exist. File successfully created: $CrFile{$Line} Time(s)\n"; | |
372 | 372 | } |
373 | 373 | } |
374 | 374 | |
444 | 444 | print "\nFailed to get Domain Master node name: $GetDomainMasterStatusFail Time(s)\n"; |
445 | 445 | } |
446 | 446 | |
447 | if (keys %GetBacupList) { | |
447 | if (keys %GetBackupList) { | |
448 | 448 | print "\nBackup list requests:\n"; |
449 | foreach $Request (sort {$a cmp $b} keys %GetBacupList) { | |
450 | print " $Request : $GetBacupList{$Request} Time(s)\n"; | |
449 | foreach $Request (sort {$a cmp $b} keys %GetBackupList) { | |
450 | print " $Request : $GetBackupList{$Request} Time(s)\n"; | |
451 | 451 | } |
452 | 452 | } |
453 | 453 |
134 | 134 | # More init corrections -mgt |
135 | 135 | # |
136 | 136 | # Revision 1.11 2005/02/13 02:27:02 mgt |
137 | # fixed uninitalized value -mgt | |
137 | # fixed uninitialized value -mgt | |
138 | 138 | # |
139 | 139 | # Revision 1.10 2004/10/15 19:24:07 mgt |
140 | 140 | # added per service flooring -mgt |
197 | 197 | #Woody - specific, thanks to Michael Stovenour |
198 | 198 | if ($ThisLine =~ /^PAM_unix[\[\]0-9]*:/i ) { next; } |
199 | 199 | |
200 | if (( $ThisLine =~ /pam_succeed_if(\([a-zA-Z]*:[a-zA-Z]*\))?: requirement \"uid (<|>)=? 1000?\" (was|not) met by user /) or | |
200 | if (( $ThisLine =~ /pam_succeed_if(\([a-zA-Z]*:[a-zA-Z]*\))?: requirement \"uid (<|>)=? (5|10)00?\" (was|not) met by user /) or | |
201 | 201 | ( $ThisLine =~ /pam_rhosts_auth\[\d+\]: allowed to [^ ]+ as \w+/) or |
202 | 202 | ( $ThisLine =~ /pam_rhosts_auth\([^\)]+\): allowed to [^ ]+ as \w+/) or |
203 | 203 | ( $ThisLine =~ /^(.*)\(pam_unix\)/) or |
260 | 260 | ( $ThisLine =~ /userhelper.*: running (.*) with context (.*)/) or |
261 | 261 | ( $ThisLine =~ /userhelper.*: pam_thinkfinger(.*): conversation failed/) or |
262 | 262 | ( $ThisLine =~ /su: PAM [0-9] more authentication failure; .*/) or |
263 | ( $ThisLine =~ /su: No passwd entry for user '(.*)'/) or | |
263 | 264 | ( $ThisLine =~ /polkit-grant-helper\[\d+\]: granted authorization for [^ ]* to uid [0-9]* \[auth=.*\]/) or |
264 | 265 | ( $ThisLine =~ /polkit-grant-helper\[\d+\]: granted authorization for [^ ]* to session .* \[uid=[0-9]*\]/) or |
265 | 266 | ( $ThisLine =~ /polkit-grant-helper-pam\[\d+\]: pam_thinkfinger\(polkit:auth\): conversation failed/) or |
266 | ( $ThisLine =~ /polkitd\(authority=.*\): (Unr|R)egistered Authentication Agent/) or | |
267 | ( $ThisLine =~ /polkitd\(authority=.*\): Operator of unix-session:/) or | |
267 | ( $ThisLine =~ /polkitd(\(authority=.*\)|\[\d+\])?: (Unr|R)egistered Authentication Agent/) or | |
268 | ( $ThisLine =~ /polkitd(\(authority=.*\)|\[\d+\])?: Operator of unix-session:/) or | |
269 | ( $ThisLine =~ /polkitd(\(authority=.*\)|\[\d+\])?: Acquired the name [^ ]* on the system bus$/) or | |
270 | ( $ThisLine =~ /polkitd(\(authority=.*\)|\[\d+\])?: Lost the name [^ ]* - exiting$/) or | |
271 | ( $ThisLine =~ /polkitd(\(authority=.*\)|\[\d+\])?: Loading rules from directory /) or | |
272 | ( $ThisLine =~ /polkitd(\(authority=.*\)|\[\d+\])?: Finished loading, compiling and executing \d+ rules$/) or | |
268 | 273 | ( $ThisLine =~ /(gdm-session-worker|gdm-password|gnome-screensaver-dialog)\[\d+\]: gkr-pam: no password is available for user/) or |
269 | 274 | ( $ThisLine =~ /gkr-pam: the password for the login keyring was invalid/) or |
270 | 275 | ( $ThisLine =~ /groupadd\[\d+\]: group added to /) or # Details in other messages |
273 | 278 | ( $ThisLine =~ /pkexec: pam_systemd(.*): /) or |
274 | 279 | ( $ThisLine =~ /pkexec: \S+: Executing command /) or |
275 | 280 | ( $ThisLine =~ /su: pam_systemd(.*): Failed to parse message: /) or |
276 | ( $ThisLine =~ /systemd-logind\[\d+\]: (New|Removed) session/) | |
281 | ( $ThisLine =~ /pam_systemd\(su:session\): Cannot create session: Already (running in|occupied by) a session/) or | |
282 | ( $ThisLine =~ /systemd-logind\[\d+\]: Removed session/) or | |
283 | ( $ThisLine =~ /systemd-logind\[\d+\]: New seat seat\d+\./) or | |
284 | ( $ThisLine =~ /systemd-logind\[\d+\]: Watching system buttons on /) or | |
285 | ( $ThisLine =~ /systemd-logind\[\d+\]: Failed to start session scope (\S+): Transaction is destructive\./) or | |
286 | ( $ThisLine =~ /DIGEST-MD5 common mech free/) or | |
287 | ( $ThisLine =~ /sshguard\[\d+\]: Reloading rotated file /) or | |
288 | ( $ThisLine =~ /sshguard\[\d+\]: Exiting on signal/) or | |
289 | ( $ThisLine =~ /sshguard\[\d+\]: Monitoring attacks from /) or | |
290 | ( $ThisLine =~ /sshguard\[\d+\]: (?:message repeated \d+ times: \[ )?\S+: not blocking /) or | |
291 | ( $ThisLine =~ /sshguard\[\d+\]: Received EOF from stdin/) or | |
292 | 0 # This line prevents blame shifting as lines are added above | |
277 | 293 | ) { |
278 | 294 | # Ignore these entries |
279 | 295 | } elsif ($ThisLine =~ /^spop3d/ || $ThisLine =~ /^pop\(\w+\)\[\d+\]:/) { |
393 | 409 | $DeletedUsers .= " $ThisLine\n"; |
394 | 410 | } elsif ( $ThisLine =~ s/^(?:useradd|adduser)(?:\[\d+\])?: new user: name=(.+), (?:uid|UID)=(\d+).*$/$1 ($2)/ ) { |
395 | 411 | $NewUsers .= " $ThisLine\n"; |
396 | } elsif ( $ThisLine =~ s/^userdel(?:\[\d+\])?: remove(?:d)? group [`'](\S+)'( owned by \S+)?/$1/ ) { | |
412 | } elsif ( $ThisLine =~ s/^userdel(?:\[\d+\])?: remove(?:d)? (?:shadow)? group [`'](\S+)'( owned by \S+)?/$1/ ) { | |
397 | 413 | $DeletedGroups .= " $ThisLine\n"; |
398 | 414 | } elsif ( $ThisLine =~ s/^groupdel(?:\[\d+\])?: remove group `(.+)'/$1/ ) { |
399 | 415 | $DeletedGroups .= " $ThisLine\n"; |
400 | 416 | } elsif ( $ThisLine =~ s/^(?:useradd|adduser)(?:\[\d+\])?: new group: name=(.+), (?:gid|GID)=(\d+).*$/$1 ($2)/ ) { |
401 | 417 | $NewGroups .= " $ThisLine\n"; |
402 | 418 | } elsif ( (undef,$User,,undef,$Group) = ($ThisLine =~ /(usermod|useradd)(?:\[\d+\])?: add [`']([^ ]+)' to (shadow ?|)group [`']([^ ]+)'/ )) { |
419 | $AddToGroup{$Group}{$User}++; | |
420 | } elsif ( ($User,undef,$Group) = ($ThisLine =~ /gpasswd: user (.+) added by (.+) to group (.+)/)) { | |
403 | 421 | $AddToGroup{$Group}{$User}++; |
404 | 422 | } elsif ( $ThisLine =~ s/^groupadd(?:\[\d+\])?: new group: name=(.+), (?:gid|GID)=(\d+).*$/$1 ($2)/ ) { |
405 | 423 | $NewGroups .= " $ThisLine\n"; |
440 | 458 | $GroupChanged{"$ThisLine"}++; |
441 | 459 | } elsif ( ($Pid,$User,$Home,$NewHome) = ($ThisLine =~ /^usermod(\[\d+\])?: change user [`'](.*)' home from [`'](.*)' to [`'](.*)'/)) { |
442 | 460 | $HomeChange{$User}{"$Home -> $NewHome"}++; |
443 | } elsif ( ($User,$From,$To) = ($ThisLine =~ /^usermod(\[\d+\])?:change user `(.*)' UID from `(.*)' to `(.*)'/)) { | |
461 | } elsif ( ($User,$From,$To) = ($ThisLine =~ /^usermod(\[\d+\])?: ?change user [`'](.*)' UID from [`'](.*)' to [`'](.*)'/)) { | |
444 | 462 | $UidChange{"$User: $From -> $To"}++; |
445 | } elsif ( ($User,$From,$To) = ($ThisLine =~ /^usermod(\[\d+\])?: change user `(.*)' GID from `(.*)' to `(.*)'/)) { | |
463 | } elsif ( ($User,$From,$To) = ($ThisLine =~ /^usermod(\[\d+\])?: ?change user [`'](.*)' GID from [`'](.*)' to [`'](.*)'/)) { | |
446 | 464 | $GidChange{"$User: $From -> $To"}++; |
465 | } elsif ( ($User,$From,$To) = ($ThisLine =~ /^usermod(\[\d+\])?: ?change user [`'](.*)' expiration from [`'](.*)' to [`'](.*)'/)) { | |
466 | $AccountExpiry{"$User: $From -> $To"}++; | |
447 | 467 | # checkpassword-pam |
448 | 468 | } elsif ( ($PID) = ($ThisLine =~ /^checkpassword-pam\[(\d+)\]: Reading username and password/)) { |
449 | 469 | } elsif ( ($PID,$Username) = ($ThisLine =~ /^checkpassword-pam\[(\d+)\]: Username '([^']+)'/)) { |
477 | 497 | $Su_User{$User}{$Su}++; |
478 | 498 | } elsif ($ThisLine =~ /^userhelper\[\d+\]: running '([^']+)' with ([^']+) privileges on behalf of '([^']+)'/) { |
479 | 499 | $Executed_app{"$1,$2,$3"}++; |
480 | } elsif ( ($User) = $ThisLine =~ /change user `([^']+)' password/) { | |
500 | } elsif ( ($User) = $ThisLine =~ /change user [`']([^']+)' password/) { | |
481 | 501 | $PwdChange{"$User"}++; |
482 | 502 | } elsif ( ($User) = ($ThisLine =~ /^cvs: password mismatch for ([^']+): ([^']+) vs. ([^']+)/) ){ |
483 | 503 | $cvs_passwd_mismatch{$User}++; |
484 | 504 | } elsif ( ($User,$From,$To) = ($ThisLine =~ /usermod\[[0-9]*\]: change user `([^ ]*)' shell from `([^ ]*)' to `([^ ]*)'/) ) { |
485 | 505 | $ChangedShell{"$User,$From,$To"}++; |
506 | } elsif ( ($User,$To) = ($ThisLine =~ /chsh\[[0-9]*\]: change user [`']([^ ]*)' shell to [`']([^ ]*)'/) ) { | |
507 | $ChangedShell{"$User,,$To"}++; | |
486 | 508 | } elsif ( ($Name1,$Name2) = ($ThisLine =~ /usermod\[[0-9]*\]: change user name `([^ ]*)' to `([^ ]*)'/)) { |
487 | 509 | $ChangedUserName{"$Name1,$Name2"}++; |
488 | 510 | } elsif (($Name,$GID) = ($ThisLine =~ /change GID for `([^ ]*)' to ([0-9]*)/)) { |
535 | 557 | } elsif (my ($mins, $secs) = ($ThisLine =~ /Scanning took ([0-9]*) minutes? and ([0-9]*) seconds?/)) { |
536 | 558 | $RootkitHunter{'time'}+= $mins*60 + $secs; |
537 | 559 | } |
560 | } elsif ($ThisLine =~ /systemd-logind(?:\[\d+\])?: New session \d+ of user (\w+)\./){ | |
561 | $UserLogin{$1}++; | |
538 | 562 | } else { |
539 | 563 | # Unmatched entries... |
540 | 564 | $ThisLine =~ s/\[\d+\]:/:/; |
754 | 778 | |
755 | 779 | if (keys %Su_User) { |
756 | 780 | print "\nUsers performing Su Changes:\n"; |
757 | foreach $User ( keys %Su_User) { | |
781 | foreach $User (sort {$a cmp $b} keys %Su_User) { | |
758 | 782 | print " $User:\n"; |
759 | 783 | foreach $Su ( keys %{$Su_User{$User}}) { |
760 | 784 | my $val = $Su_User{$User}{$Su}; |
765 | 789 | |
766 | 790 | if ($ConsoleLock > 0) { |
767 | 791 | print "\nConsole file lock already in place: $ConsoleLock Time(s).\n"; |
792 | } | |
793 | ||
794 | if (keys %AccountExpiry) { | |
795 | print "\nChanged account expiry for users:\n"; | |
796 | foreach $User (sort {$a cmp $b} keys %AccountExpiry) { | |
797 | print " $User : $AccountExpiry{$User} Time(s)\n"; | |
798 | } | |
768 | 799 | } |
769 | 800 | |
770 | 801 | if (keys %PasswordExpiry) { |
843 | 874 | print "\nUserhelper executed applications:\n"; |
844 | 875 | foreach (keys %Executed_app) { |
845 | 876 | ($longapp,$asuser,$user) = split ","; |
877 | $longapp_orig = $longapp; | |
878 | $i = index($longapp, " "); | |
879 | if ($i > 0) { | |
880 | $longapp = substr($longapp, 0, $i); | |
881 | } | |
846 | 882 | $app = substr($longapp,rindex($longapp,"/")+1); |
847 | print " $user -> $app as $asuser: ".$Executed_app{"$longapp,$asuser,$user"}." Time(s)\n"; | |
883 | print " $user -> $app as $asuser: ".$Executed_app{"$longapp_orig,$asuser,$user"}." Time(s)\n"; | |
848 | 884 | } |
849 | 885 | } |
850 | 886 | |
868 | 904 | print "\nChanged users default login shell: \n"; |
869 | 905 | foreach (keys %ChangedShell) { |
870 | 906 | ($User,$From,$To) = split ","; |
871 | print " User " . $User . " change shell from " . $From . " to " . $To . ": " . $ChangedShell{"$User,$From,$To"} . " Time(s)\n"; | |
907 | if ($From ne '') { | |
908 | print " User " . $User . " change shell from " . $From . " to " . $To . ": " . $ChangedShell{"$User,$From,$To"} . " Time(s)\n"; | |
909 | } else { | |
910 | print " User " . $User . " change shell to " . $To . ": " . $ChangedShell{"$User,$From,$To"} . " Time(s)\n"; | |
911 | } | |
872 | 912 | } |
873 | 913 | |
874 | 914 | } |
143 | 143 | # Added another blackhole line to catch 553 rejects with no relay tag -mgt |
144 | 144 | # |
145 | 145 | # Revision 1.53 2005/05/26 22:20:45 mike |
146 | # Added blackholethreshold to supress very noisy blackhole lists -mgt | |
146 | # Added blackholethreshold to suppress very noisy blackhole lists -mgt | |
147 | 147 | # |
148 | 148 | # Revision 1.52 2005/05/21 22:51:24 bjorn |
149 | 149 | # Cleaned up code to print headers only when something to report. Basic |
564 | 564 | ( $ThisLine =~ /^STARTTLS: write error=syscall error \(-1\), errno=${\Errno::ECONNRESET}/ ) or |
565 | 565 | # file=srvsmtp.c, LogLevel>5, LOG_WARNING |
566 | 566 | ( $ThisLine =~ /^STARTTLS=server, error: accept failed=-1, reason=unknown, SSL_error=5, errno=${\Errno::ECONNRESET}, retry=/ ) or |
567 | # and yet another sympton of a connection shut down (EPIPE refers to "Broken pipe") | |
567 | # and yet another symptom of a connection shut down (EPIPE refers to "Broken pipe") | |
568 | 568 | # file=srvsmtp.c, LogLevel>5, LOG_WARNING |
569 | 569 | ( $ThisLine =~ /^STARTTLS=server, error: accept failed=-1, reason=unknown, SSL_error=5, errno=${\Errno::EPIPE}, retry=/ ) or |
570 | 570 | # the following is a log message introduced in 8.13.6 |
828 | 828 | } elsif ( ($RelayHost,$User) = ($ThisLine =~ /^ruleset=check_(?:mail|rcpt), arg1=.*, relay=(.*), reject=553\s*[\d.]*\s*.*\.\.\. Domain of sender address (.*) does not exist/) ) { |
829 | 829 | $User =~ s/^.+\@(.+)$/$1/ if ($Detail < 15); |
830 | 830 | $DomainErrors{$RelayHost}{$User . " (sender does not exist)"}++; |
831 | $Msgs{$QueueID}{"BadRCPT"}++; | |
831 | 832 | # file: sendmail.cf |
832 | 833 | } elsif ( ($User,$RelayHost) = ($ThisLine =~ /^ruleset=check_mail, arg1=(.*), relay=(.*), reject=553\s*[\d.]*\s*.*\.\.\. Domain name required for sender address .*/) ) { |
833 | 834 | $DomainErrors{$RelayHost}{$User . " (sender domain missing)"}++; |
1353 | 1354 | print "\n\nSendmail was started $SendmailStarts time(s)"; |
1354 | 1355 | } |
1355 | 1356 | printf("\n\nMessages To Recipients:%11d", $MsgsSent); |
1356 | # Each explicitely addressed recipient in an email is counted as an | |
1357 | # Each explicitly addressed recipient in an email is counted as an | |
1357 | 1358 | # "Addressed Recipient" |
1358 | 1359 | printf("\nAddressed Recipients:%13d", $AddrRcpts); |
1359 | 1360 | printf("\nBytes Transferred:%16d", $BytesTransferred); |
28 | 28 | # - ignored some entries |
29 | 29 | # |
30 | 30 | # Revision 1.2 2004/01/06 10:57:33 blues |
31 | # - delay decreating message | |
31 | # - delay decreasing message | |
32 | 32 | # |
33 | 33 | # Revision 1.1 2003/12/25 20:07:15 blues |
34 | 34 | # - shaperd support for logwatch |
95 | 95 | } elsif ( ($Delay) = ( $ThisLine =~ /^Decreasing delay to ([0-9]*) seconds$/) ) { |
96 | 96 | $DecreasingDelay{$Delay}++; |
97 | 97 | $DelayDecCount++; |
98 | } elsif ( $ThisLine =~ m/^It seems that iproute2 did'nt work correctly. Please upgrade your iproute2 and\/or kernel./) { | |
98 | } elsif ( $ThisLine =~ m/^It seems that iproute2 didn't work correctly. Please upgrade your iproute2 and\/or kernel./) { | |
99 | 99 | $TooOldSoft++; |
100 | 100 | } else { |
101 | 101 | $OtherList{$ThisLine}++; |
554 | 554 | } |
555 | 555 | |
556 | 556 | if (keys %SyslogHost) { |
557 | print "\nDevice where Syslog have been mail succesfully :\n"; | |
557 | print "\nDevice where Syslog have been mail successfully :\n"; | |
558 | 558 | foreach $ThisOne (keys %SyslogHost) { |
559 | 559 | print " " . $ThisOne . ":\n"; |
560 | 560 | foreach $ThatOne (keys %{$SyslogHost{$ThisOne}}) { |
187 | 187 | |
188 | 188 | # No sense in running if 'sshd' doesn't even exist on this system... |
189 | 189 | #unless (( -f "/usr/sbin/sshd" ) or ( -f "/usr/local/sbin/sshd") or ( -f "/usr/lib/ssh/sshd")) { |
190 | # exit (0); | |
190 | # exit (0); | |
191 | 191 | #} |
192 | 192 | |
193 | 193 | my %Users = (); |
200 | 200 | my %NoRevMap = (); |
201 | 201 | my %RefusedConnections = (); |
202 | 202 | my %RefusedAuthentication = (); |
203 | my %NegotiationFailed = (); | |
203 | 204 | my %DisconnectReceived = (); |
204 | 205 | my %RootLogin = (); |
205 | 206 | my %PamReleaseFail = (); |
206 | 207 | my %PamError = (); |
207 | 208 | my %PamChroot = (); |
209 | my %PamDeny = (); | |
208 | 210 | my %ShadowInfo = (); |
209 | 211 | my %TTYModesFail = (); |
210 | 212 | my %LoginLock = (); |
222 | 224 | my %KrbAutFail = (); |
223 | 225 | my %KrbAutErr = (); |
224 | 226 | my %KrbErr = (); |
225 | my @BadRSA = (); | |
226 | 227 | my @Scanned = (); |
227 | 228 | my %OtherList = (); |
228 | 229 | my %ChmodErr = (); |
229 | 230 | my %ChownErr = (); |
230 | my %Krb_relm = (); | |
231 | my %Krb_realm = (); | |
232 | my %ConnectFailed = (); | |
233 | my %Chroot = (); | |
234 | my %CloseDir = (); | |
235 | my %CloseFileReadWrite = (); | |
236 | my %OpenDir = (); | |
237 | my %OpenFile = (); | |
238 | my %RealPath = (); | |
239 | my %Session = (); | |
240 | my %SetModtime = (); | |
241 | my %Stat = (); | |
242 | my %ClientVers = (); | |
231 | 243 | |
232 | 244 | my $sftpRequests = 0; |
233 | 245 | my $NetworkErrors = 0; |
234 | 246 | my $Kills = 0; |
235 | 247 | my $Starts = 0; |
236 | 248 | my $NetworkErrors = 0; |
249 | my $StatusNoSuchFile = 0; | |
250 | my $BytesSent = 0; | |
251 | my $BytesReceived = 0; | |
237 | 252 | |
238 | 253 | if ( $Debug >= 5 ) { |
239 | 254 | print STDERR "\n\nDEBUG: Inside SSHD Filter \n\n"; |
272 | 287 | ($ThisLine =~ m/^channel_lookup: -?\d+: bad id/) or |
273 | 288 | ($ThisLine =~ m/^error: channel \d+: chan_read_failed for istate/) or |
274 | 289 | # Result of setting PermitRootLogin to forced-commands-only |
275 | ($ThisLine =~ m/^Root login accepted for forced command.$/) or | |
290 | ($ThisLine =~ m/^Root login accepted for forced command\.( \[preauth\])?$/) or | |
276 | 291 | # usually followed by a session opened for user |
277 | 292 | ($ThisLine =~ m/^pam_krb5\[\d+\]: authentication succeeds for /) or |
278 | 293 | ($ThisLine =~ m/^nss_ldap: reconnect/) or |
282 | 297 | ($ThisLine =~ m/^\(pam_unix\) .*/) or |
283 | 298 | ($ThisLine =~ m/^pam_unix\(.*:.*\)/) or |
284 | 299 | ($ThisLine =~ m/^pam_unix_auth:/) or |
300 | ($ThisLine =~ m/^pam_sepermit\(.*:.*\)/) or | |
285 | 301 | ($ThisLine =~ /pam_krb5: authentication succeeds for `([^ ]*)'/) or |
286 | 302 | ($ThisLine =~ /pam_succeed_if\(.*:.*\): error retrieving information about user [a-zA-Z]*/ ) or |
287 | 303 | ($ThisLine =~ /pam_winbind\(sshd:account\): user .* granted access/) or |
288 | 304 | ($ThisLine =~ /pam_winbind\(sshd:account\): user .* OK/) or |
289 | 305 | ($ThisLine =~ /pam_systemd\(sshd:session\): Moving/) or |
306 | ($ThisLine =~ /pam_systemd\(sshd:session\): .*: Connection reset by peer/) or | |
290 | 307 | ($ThisLine =~ /PAM \d+ more authentication failures?;/) or |
291 | 308 | ($ThisLine =~ /^PAM service\(sshd\) ignoring max retries;/) or |
292 | 309 | ($ThisLine =~ /^Failed keyboard-interactive for <invalid username> from/ ) or |
296 | 313 | ($ThisLine =~ /Starting session: (forced-command|subsystem|shell|command)/ ) or |
297 | 314 | ($ThisLine =~ /Found matching \w+ key:/ ) or |
298 | 315 | ($ThisLine =~ /User child is on pid \d/ ) or |
299 | ($ThisLine =~ /Nasty PTR record .* is set up for [\da-fA-F.:]+, ignoring/) | |
316 | ($ThisLine =~ /Nasty PTR record .* is set up for [\da-fA-F.:]+, ignoring/) or | |
317 | ($ThisLine =~ /Disconnected from (?:user \S+ |)[\da-fA-F.:]* port \d*/ ) or | |
318 | ($ThisLine =~ /Failed to release session: Interrupted system call/) or | |
319 | ($ThisLine =~ /Close session: user /) or | |
320 | 0 # This line prevents blame shifting as lines are added above | |
300 | 321 | ) { |
301 | 322 | # Ignore these |
302 | } elsif ( my ($Method,$User,$Host,$Port,$Key) = ($ThisLine =~ /^Accepted (\S+) for ((?:invalid user )?\S+) from ([\d\.:a-f]+) port (\d+) ssh[12](?:: (\w+))?/) ) { | |
323 | } elsif ( my ($Method,$User,$Host,$Port,$Key,$FingerP) = ($ThisLine =~ /^Accepted (\S+) for ((?:invalid user )?\S+) from ([\d\.:a-f]+)(?:%\w+)? port (\d+) ssh[12](?:: (\w+) (.+))?/) ) { | |
303 | 324 | if ($Debug >= 5) { |
304 | 325 | print STDERR "DEBUG: Found -$User logged in from $Host using $Method ($Key)\n"; |
305 | 326 | } |
306 | 327 | if ($Detail >= 20) { |
307 | $Users{$User}{$Host}{$Method . ($Key ? " ($Key)" : "")}++; | |
328 | $Users{$User}{$Host}{$Method . ($Key ? | |
329 | "($Key" . (($Detail >= 30) ? " " . $FingerP : "") . ")" : | |
330 | "")}++; | |
308 | 331 | } else { |
309 | 332 | if ( $Host !~ /$IgnoreHost/ ) { |
310 | 333 | $Users{$User}{$Host}{"(all)"}++; |
314 | 337 | $IllegalUsers{$Host}{$User}++; |
315 | 338 | } elsif ( my ($User) = ( $ThisLine =~ /Disconnecting: Too many authentication failures for ([^ ]+)/)) { |
316 | 339 | $TooManyFailures{$User}++; |
340 | } elsif ( my ($User) = ( $ThisLine =~ /error: maximum authentication attempts exceeded for ([^ ]+) from [^ ]+ port \d+ ssh2 \[preauth\]/)) { | |
341 | $TooManyFailures{$User}++; | |
342 | } elsif ( $ThisLine =~ /Disconnecting: Too many authentication failures \[preauth\]/ ) { | |
343 | # Ignore these - should be covered by other messages | |
317 | 344 | } elsif ( $ThisLine =~ m/^(fatal: )?Did not receive ident(ification)? string from (.+)/ ) { # ssh/openssh |
318 | 345 | my $name = LookupIP($3); |
319 | 346 | $NoIdent{$name}++; |
328 | 355 | ($ThisLine =~ m/^fatal: Write failed: Network is unreachable/ ) or |
329 | 356 | ($ThisLine =~ m/^fatal: Write failed: Broken pipe/) or |
330 | 357 | ($ThisLine =~ m/^fatal: Write failed: Connection reset by peer/) or |
358 | ($ThisLine =~ m/^Connection reset by/) or | |
331 | 359 | ($ThisLine =~ m/^channel \d+: open failed: (?:connect failed: Channel open failed\.|administratively prohibited: open failed)/) or |
332 | 360 | ($ThisLine =~ m/^session_input_channel_req: no session \d+ req window-change/) or |
333 | 361 | ($ThisLine =~ m/^error: chan_shutdown_read failed for .+/) |
386 | 414 | $RefusedConnections{$1}++; |
387 | 415 | } elsif ( my ($Reason) = ($ThisLine =~ /^Authentication refused: (.*)$/ ) ) { |
388 | 416 | $RefusedAuthentication{$Reason}++; |
389 | } elsif ( my ($Host,$Reason) = ($ThisLine =~ /^Received disconnect from ([^ ]*)(?: port [^ ]*)?: (.*)$/)) { | |
390 | # Reason 11 (SSH_DISCONNECT_BY_APPLICATION) is expected, and logged at severity level INFO | |
391 | if ($Reason != 11) {$DisconnectReceived{$Reason}{$Host}++;} | |
417 | } elsif ( my (undef,$Host,$Port,$Reason,$Offer) = ($ThisLine =~ /^(fatal: )?Unable to negotiate with ([^ ]+)( port \d+)?: (.*)\. Their offer: (.*) \[preauth\]$/) ) { | |
418 | $NegotiationFailed{$Reason}{$Host}{$Offer}++; | |
419 | } elsif ( my ($Reason,$Host,$Offer) = ($ThisLine =~ /^(Protocol major versions differ) for ([^ ]+)(?: port \d+): (.*)$/) ) { | |
420 | $NegotiationFailed{$Reason}{$Host}{$Offer}++; | |
421 | } elsif ( my ($Prio,$Host,$Port,$Code,$Reason) = ($ThisLine =~ /^(error: )?Received disconnect from ([^ ]*)( port \d+)?: ?(\d+): (.*)$/)) { | |
422 | # Reason 11 ({SSH,SSH2}_DISCONNECT_BY_APPLICATION) is expected, and logged at severity level INFO | |
423 | if (($Code != 11) || ($Detail >= 30)) { | |
424 | $DisconnectReceived{$Reason}{$Host}++; | |
425 | } | |
392 | 426 | } elsif ( my ($Host) = ($ThisLine =~ /^ROOT LOGIN REFUSED FROM ([^ ]*)$/)) { |
393 | 427 | $RootLogin{$Host}++; |
394 | 428 | } elsif ( my ($Error) = ($ThisLine =~ /^Cannot release PAM authentication\[\d\]: (.*)$/)) { |
422 | 456 | $NoShellUsers{$User}++; |
423 | 457 | } elsif ( ($User) = ($ThisLine =~ /^User ([^ ]*) not allowed because shell (\S+) is not executable/)) { |
424 | 458 | $ShellNotExecutableUsers{$User}++; |
459 | } elsif ( ($User) = ($ThisLine =~ /^fatal: Access denied for user ([^ ]+) by PAM account configuration \[preauth\]/)) { | |
460 | $PamDeny{$User}++; | |
425 | 461 | } elsif ( my ($IP) = ($ThisLine =~ /^scanned from ([^ ]*)/) ) { |
426 | 462 | push @Scanned, $IP; |
427 | } elsif ( my ($Line,$Option) = ($ThisLine =~ /^rexec line (\d+): Deprecated option (.*)$/)) { | |
463 | } elsif ( my (undef,$Line,$Option) = ($ThisLine =~ /^re(xec|process config) line (\d+): Deprecated option (.*)$/)) { | |
428 | 464 | $DeprecatedOption{"$Option - line $Line"}++; |
429 | 465 | } elsif ( my ($Pom1,$Pom2,$User) = ($ThisLine =~ /pam_krb5(\[\d*\])?: authentication fails for (`|')([^ ]*)'/)) { |
430 | 466 | $KrbAutFail{$User}++; |
439 | 475 | } elsif ( my (undef,$User,$Host) = ($ThisLine =~ m/^(Illegal|Invalid) user (.*) from ([^ ]+)/ )) { |
440 | 476 | $PotentialIllegalUsers{$Host}{$User}++; |
441 | 477 | } elsif ( my (undef,$User) = ($ThisLine =~ /^input_userauth_request: (illegal|invalid) user (.*)$/ )) { |
478 | if ($User =~ m/(.*) \[preauth\]/) { | |
479 | $User = $1; | |
480 | } | |
442 | 481 | $PotentialIllegalUsers{"undef"}{$User}++; |
443 | 482 | } elsif (my ($File,$Perm,$Why) = ($ThisLine =~ /error: chmod (.*) (.*) failed: (.*)/)) { |
444 | 483 | $ChmodErr{"$File,$Perm,$Why"}++; |
445 | 484 | } elsif (my ($File,$From,$To,$Why) = ($ThisLine =~ /error: chown (.*) (.*) (.*) failed: (.*)/)) { |
446 | 485 | $ChownErr{"$File,$From,$To,$Why"}++; |
447 | } elsif (my ($user,$relm) = ($ThisLine =~ /Authorized to ([^ ]+), krb5 principal \1@([^ ]+) \(krb5_kuserok\)/)) { | |
448 | $Krb_relm{$relm}{$user}++; | |
486 | } elsif (my ($user,$realm) = ($ThisLine =~ /Authorized to ([^ ]+), krb5 principal \1@([^ ]+) \((?:krb5_kuserok|ssh_gssapi_krb5_cmdok)\)/)) { | |
487 | $Krb_realm{$realm}{$user}++; | |
488 | } elsif (my ($Action,$User) = ($ThisLine =~ /^session ((?:open|clos)ed) for local user (\S+) from /)) { | |
489 | $Session{"Action,$User"}++; | |
490 | } elsif ($ThisLine =~ /^sent status No such file$/) { | |
491 | $StatusNoSuchFile++; | |
492 | } elsif (my ($File,$Flags,$Mode) = ($ThisLine =~ /^open "(.*)" flags (\S+) mode (\d+)/ )) { | |
493 | $OpenFile{"$File:$Flags:$Mode"}++; | |
494 | } elsif (my ($File,$BytesRead,$BytesWritten) = ($ThisLine =~ /^close "(.*)" bytes read (\d+) written (\d+)/ )) { | |
495 | $CloseFileReadWrite{"$File,$BytesRead,$BytesWritten"}++; | |
496 | } elsif (my ($Sent,$Received) = ($ThisLine =~ /^Transferred: sent (\d+), received (\d+) bytes$/ )) { | |
497 | $BytesSent += $Sent; | |
498 | $BytesReceived += $Received; | |
499 | } elsif (my ($File,$Modtime) = ($ThisLine =~ /^set "(.*)" modtime (\d+-\d+:\d+:\d+)$/ )) { | |
500 | $SetModtime{"$Modtime,$File"}++; | |
501 | } elsif (my ($Dir) = ($ThisLine =~ /^opendir "(.*)"$/ )) { | |
502 | $OpenDir{$Dir}++; | |
503 | } elsif (my ($Dir) = ($ThisLine =~ /^closedir "(.*)"$/ )) { | |
504 | $CloseDir{$Dir}++; | |
505 | } elsif (my ($File) = ($ThisLine =~ /^realpath "(.*)"$/ )) { | |
506 | $RealPath{$File}++; | |
507 | } elsif (my ($File) = ($ThisLine =~ /^stat name "(.*)"$/ )) { | |
508 | $Stat{$File}++; | |
509 | } elsif (my ($Dir) = ($ThisLine =~ /^Changed root directory to "(.*)"/ )) { | |
510 | $Chroot{$Dir}++; | |
511 | } elsif (my ($ClientVer) = ($ThisLine =~ /^received client version (\S+)/ )) { | |
512 | $ClientVers{$ClientVer}++; | |
513 | } elsif (my ($Host,$Port) = ($ThisLine =~ /^error: connect_to (\S+) port (\d+): failed\.$/)) { | |
514 | $ConnectFailed{"$Host port $Port"}++; | |
449 | 515 | } else { |
450 | 516 | # Report any unmatched entries... |
451 | 517 | unless ($ThisLine =~ /fwd X11 connect/) { |
456 | 522 | |
457 | 523 | ########################################################### |
458 | 524 | |
459 | foreach my $Host (keys %PotentialIllegalUsers) { | |
460 | foreach my $User (keys %{$PotentialIllegalUsers{$Host}}) { | |
525 | foreach my $Host (sort keys %PotentialIllegalUsers) { | |
526 | foreach my $User (sort keys %{$PotentialIllegalUsers{$Host}}) { | |
461 | 527 | my @user_hosts = grep { $PotentialIllegalUsers{$_}{$User} } keys %PotentialIllegalUsers; |
462 | 528 | |
463 | 529 | if ($Host eq "undef") { |
477 | 543 | |
478 | 544 | ########################################################### |
479 | 545 | |
546 | sub timesplural { | |
547 | my ($count) = @_; | |
548 | my $plural = ($count > 1) ? "s" : ""; | |
549 | return "$count Time$plural\n"; | |
550 | } | |
551 | ||
480 | 552 | if ($NetworkErrors) { |
481 | 553 | print "\nNetwork Read Write Errors: " . $NetworkErrors . "\n"; |
482 | 554 | } |
483 | 555 | if ($Kills) { |
484 | print "\nSSHD Killed: " . $Kills . " Time(s)\n"; | |
556 | print "\nSSHD Killed: " . timesplural($Kills); | |
485 | 557 | } |
486 | 558 | if ($Starts) { |
487 | print "\nSSHD Started: " . $Starts . " Time(s)\n"; | |
559 | print "\nSSHD Started: " . timesplural($Starts); | |
488 | 560 | } |
489 | 561 | |
490 | 562 | if (keys %DeprecatedOption) { |
498 | 570 | print "\n\nWARNING!!!\n"; |
499 | 571 | print "Refused ROOT login attempt from:\n"; |
500 | 572 | foreach my $Host (sort {$a cmp $b} keys %RootLogin) { |
501 | print " $Host : $RootLogin{$Host} Time(s)\n"; | |
573 | print " $Host : " . timesplural($RootLogin{$Host}); | |
502 | 574 | } |
503 | 575 | } |
504 | 576 | |
505 | 577 | if (keys %BindFailed) { |
506 | 578 | print "\nFailed to bind:\n"; |
507 | 579 | foreach my $ThisOne (sort {$a cmp $b} keys %BindFailed) { |
508 | print " $ThisOne : $BindFailed{$ThisOne} Time(s)\n"; | |
580 | print " $ThisOne : " . timesplural($BindFailed{$ThisOne}); | |
581 | } | |
582 | } | |
583 | ||
584 | if ($Detail >= 30 && keys %ConnectFailed) { | |
585 | # SSH Socks Forwarding | |
586 | print "\nFailed to connect to:\n"; | |
587 | foreach my $ThisOne (sort {$a cmp $b} keys %ConnectFailed) { | |
588 | print " $ThisOne : " . timesplural($ConnectFailed{$ThisOne}); | |
509 | 589 | } |
510 | 590 | } |
511 | 591 | |
513 | 593 | if (keys %NoRevMap) { |
514 | 594 | print "\nCouldn't resolve these IPs:\n"; |
515 | 595 | foreach my $ThisOne (sort {$a cmp $b} keys %NoRevMap) { |
516 | print " $ThisOne: $NoRevMap{$ThisOne} Time(s)\n"; | |
596 | print " $ThisOne: " . timesplural($NoRevMap{$ThisOne}); | |
517 | 597 | } |
518 | 598 | } |
519 | 599 | if (keys %NoIdent) { |
520 | 600 | print "\nDidn't receive an ident from these IPs:\n"; |
521 | 601 | foreach my $ThisOne (sort {$a cmp $b} keys %NoIdent) { |
522 | print " $ThisOne: $NoIdent{$ThisOne} Time(s)\n"; | |
602 | print " $ThisOne: " . timesplural($NoIdent{$ThisOne}); | |
523 | 603 | } |
524 | 604 | } |
525 | 605 | if (keys %MisMatch) { |
526 | 606 | print "\nMismatched host names and/or IPs:\n"; |
527 | 607 | foreach my $ThisOne (sort keys %MisMatch) { |
528 | print " $ThisOne: $MisMatch{$ThisOne} Time(s)\n"; | |
529 | } | |
530 | } | |
531 | } | |
532 | ||
533 | if ($#BadRSA >= 0) { | |
534 | print "\nReceived a bad response to RSA challenge from:\n"; | |
535 | foreach my $ThisOne (@BadRSA) { | |
536 | print " $ThisOne\n"; | |
608 | print " $ThisOne: " . timesplural($MisMatch{$ThisOne}); | |
609 | } | |
610 | } | |
611 | } | |
612 | ||
613 | if (keys %NegotiationFailed) { | |
614 | print "\nNegotiation failed:\n"; | |
615 | foreach my $Reason (sort {$a cmp $b} keys %NegotiationFailed) { | |
616 | my $Total = 0; | |
617 | print " $Reason"; | |
618 | foreach my $Host (sort {$a cmp $b} keys %{$NegotiationFailed{$Reason}}) { | |
619 | my $HostTotal = 0; | |
620 | foreach my $Offer (sort {$a cmp $b} keys %{$NegotiationFailed{$Reason}{$Host}}) { | |
621 | $HostTotal += $NegotiationFailed{$Reason}{$Host}{$Offer}; | |
622 | } | |
623 | $Total += $HostTotal; | |
624 | if ( $Detail > 0 ) { | |
625 | print "\n $Host: " . timesplural($HostTotal); | |
626 | } | |
627 | if ( $Detail > 5 ) { | |
628 | foreach my $Offer (sort {$a cmp $b} keys %{$NegotiationFailed{$Reason}{$Host}}) { | |
629 | my $tot = $NegotiationFailed{$Reason}{$Host}{$Offer}; | |
630 | print "\n $Offer: " . timesplural($tot); | |
631 | } | |
632 | } | |
633 | } | |
634 | if( $Detail > 0 ) { | |
635 | print "\n"; | |
636 | } else { | |
637 | print ": " . timesplural($Total); | |
638 | } | |
537 | 639 | } |
538 | 640 | } |
539 | 641 | |
540 | 642 | if (keys %TooManyFailures) { |
541 | 643 | print "\nDisconnecting after too many authentication failures for user:\n"; |
542 | 644 | foreach my $User (sort {$a cmp $b} keys %TooManyFailures) { |
543 | print " $User : $TooManyFailures{$User} Time(s)\n"; | |
645 | print " $User : " . timesplural($TooManyFailures{$User}); | |
544 | 646 | } |
545 | 647 | } |
546 | 648 | |
552 | 654 | foreach my $user (keys %{$BadLogins{$ip}}) { |
553 | 655 | $totcount += $BadLogins{$ip}{$user}; |
554 | 656 | } |
555 | my $plural = ($totcount > 1) ? "s" : ""; | |
556 | print " $name: $totcount time$plural\n"; | |
657 | print " $name: ". timesplural($totcount); | |
557 | 658 | if ($Detail >= 5) { |
558 | 659 | my $sort = CountOrder(%{$BadLogins{$ip}}); |
559 | 660 | foreach my $user (sort $sort keys %{$BadLogins{$ip}}) { |
560 | 661 | my $val = $BadLogins{$ip}{$user}; |
561 | my $plural = ($val > 1) ? "s" : ""; | |
562 | print " $user: $val time$plural\n"; | |
662 | print " $user: " . timesplural($val); | |
563 | 663 | } |
564 | 664 | } |
565 | 665 | } |
573 | 673 | foreach my $user (keys %{$IllegalUsers{$ip}}) { |
574 | 674 | $totcount += $IllegalUsers{$ip}{$user}; |
575 | 675 | } |
576 | my $plural = ($totcount > 1) ? "s" : ""; | |
577 | print " $name: $totcount time$plural\n"; | |
676 | print " $name: " . timesplural($totcount); | |
578 | 677 | if ($Detail >= 5) { |
579 | 678 | my $sort = CountOrder(%{$IllegalUsers{$ip}}); |
580 | 679 | foreach my $user (sort $sort keys %{$IllegalUsers{$ip}}) { |
581 | 680 | my $val = $IllegalUsers{$ip}{$user}; |
582 | my $plural = ($val > 1) ? "s" : ""; | |
583 | print " $user: $val time$plural\n"; | |
681 | print " $user: " . timesplural($val); | |
584 | 682 | } |
585 | 683 | } |
586 | 684 | } |
589 | 687 | if (keys %LockedAccount) { |
590 | 688 | print "\nLocked account login attempts:\n"; |
591 | 689 | foreach my $User (sort {$a cmp $b} keys %LockedAccount) { |
592 | print " $User : $LockedAccount{$User} Time(s)\n"; | |
690 | print " $User : " . timesplural($LockedAccount{$User}); | |
593 | 691 | } |
594 | 692 | } |
595 | 693 | |
596 | 694 | if (keys %AllowUsers) { |
597 | 695 | print "\nLogin attempted when not in AllowUsers list:\n"; |
598 | 696 | foreach my $User (sort {$a cmp $b} keys %AllowUsers) { |
599 | print " $User : $AllowUsers{$User} Time(s)\n"; | |
697 | print " $User : " . timesplural($AllowUsers{$User}); | |
600 | 698 | } |
601 | 699 | } |
602 | 700 | |
603 | 701 | if (keys %DenyUsers) { |
604 | 702 | print "\nLogin attempted when in DenyUsers list:\n"; |
605 | 703 | foreach my $User (sort {$a cmp $b} keys %DenyUsers) { |
606 | print " $User : $DenyUsers{$User} Time(s)\n"; | |
704 | print " $User : . " . timesplural($DenyUsers{$User}); | |
607 | 705 | } |
608 | 706 | } |
609 | 707 | |
610 | 708 | if (keys %AllowGroups) { |
611 | 709 | print "\nLogin attempted when not in AllowGroups list:\n"; |
612 | 710 | foreach my $User (sort {$a cmp $b} keys %AllowGroups) { |
613 | print " $User : $AllowGroups{$User} Time(s)\n"; | |
711 | print " $User : " . timesplural($AllowGroups{$User}); | |
614 | 712 | } |
615 | 713 | } |
616 | 714 | |
617 | 715 | if (keys %DenyGroups) { |
618 | 716 | print "\nLogin attempted when in DenyGroups list:\n"; |
619 | 717 | foreach my $User (sort {$a cmp $b} keys %DenyGroups) { |
620 | print " $User : $DenyGroups{$User} Time(s)\n"; | |
718 | print " $User : " . timesplural($DenyGroups{$User}); | |
719 | } | |
720 | } | |
721 | ||
722 | if (keys %PamDeny) { | |
723 | print "\nLogin attempted when denied by PAM configuration:\n"; | |
724 | foreach my $User (sort {$a cmp $b} keys %PamDeny) { | |
725 | print " $User : " . timesplural($PamDeny{$User}); | |
621 | 726 | } |
622 | 727 | } |
623 | 728 | |
624 | 729 | if (keys %NoGroups) { |
625 | 730 | print "\nLogin attempted when user is in no group:\n"; |
626 | 731 | foreach my $User (sort {$a cmp $b} keys %NoGroups) { |
627 | print " $User : $NoGroups{$User} Time(s)\n"; | |
732 | print " $User : " . timesplural($NoGroups{$User}); | |
628 | 733 | } |
629 | 734 | } |
630 | 735 | |
631 | 736 | if (keys %NoShellUsers) { |
632 | 737 | print "\nLogin attempted when shell does not exist:\n"; |
633 | 738 | foreach my $User (sort {$a cmp $b} keys %NoShellUsers) { |
634 | print " $User : $NoShellUsers{$User} Time(s)\n"; | |
739 | print " $User : " . timesplural($NoShellUsers{$User}); | |
635 | 740 | } |
636 | 741 | } |
637 | 742 | |
638 | 743 | if (keys %ShellNotExecutableUsers) { |
639 | 744 | print "\nLogin attempted when shell is not executable:\n"; |
640 | 745 | foreach my $User (sort {$a cmp $b} keys %ShellNotExecutableUsers) { |
641 | print " $User : $ShellNotExecutableUsers{$User} Time(s)\n"; | |
746 | print " $User : " . timesplural($ShellNotExecutableUsers{$User}); | |
642 | 747 | } |
643 | 748 | } |
644 | 749 | |
645 | 750 | if ((keys %LoginLock) and ($Detail >= 5)) { |
646 | 751 | print "\nUser login attempt when nologin was set:\n"; |
647 | 752 | foreach my $User (sort {$a cmp $b} keys %LoginLock) { |
648 | print " $User : $LoginLock{$User} Time(s)\n"; | |
753 | print " $User : " . timesplural($LoginLock{$User}); | |
649 | 754 | } |
650 | 755 | } |
651 | 756 | |
654 | 759 | foreach my $User (sort {$a cmp $b} keys %PostPonedAuth) { |
655 | 760 | print " $User:\n"; |
656 | 761 | foreach my $Host (sort {$a cmp $b} keys %{$PostPonedAuth{$User}}) { |
657 | print " $Host: $PostPonedAuth{$User}{$Host} Time(s)\n"; | |
762 | print " $Host: " . timesplural($PostPonedAuth{$User}{$Host}); | |
658 | 763 | } |
659 | 764 | } |
660 | 765 | } |
663 | 768 | print "\nUsers logging in through sshd:\n"; |
664 | 769 | foreach my $user (sort {$a cmp $b} keys %Users) { |
665 | 770 | print " $user:\n"; |
666 | my $totalSort = TotalCountOrder(%{$Users{$user}}, \&SortIP); | |
667 | foreach my $ip (sort $totalSort keys %{$Users{$user}}) { | |
668 | my $name = LookupIP($ip); | |
669 | if ($Detail >= 20) { | |
670 | print " $name:\n"; | |
671 | my $sort = CountOrder(%{$Users{$user}{$ip}}); | |
672 | foreach my $method (sort $sort keys %{$Users{$user}{$ip}}) { | |
673 | my $val = $Users{$user}{$ip}{$method}; | |
674 | my $plural = ($val > 1) ? "s" : ""; | |
675 | print " $method: $val time$plural\n"; | |
771 | if ($Detail < 20) { | |
772 | my $totalSort = TotalCountOrder(%{$Users{$user}}, \&SortIP); | |
773 | foreach my $ip (sort $totalSort keys %{$Users{$user}}) { | |
774 | my $name = LookupIP($ip); | |
775 | my $val = (values %{$Users{$user}{$ip}})[0]; | |
776 | print " $name: " . timesplural($val); | |
777 | } | |
778 | } else { | |
779 | my %Methods = (); | |
780 | foreach my $ip (keys %{$Users{$user}}) { | |
781 | foreach my $method (keys %{$Users{$user}{$ip}}) { | |
782 | $Methods{$method}{$ip} = $Users{$user}{$ip}{$method}; | |
783 | } | |
784 | } | |
785 | if (scalar keys %{$Users{$user}} < scalar %Methods) { | |
786 | my $totalSort = TotalCountOrder(%{$Users{$user}}, \&SortIP); | |
787 | foreach my $ip (sort $totalSort keys %{$Users{$user}}) { | |
788 | my $name = LookupIP($ip); | |
789 | print " $name:\n"; | |
790 | my $sort = CountOrder(%{$Users{$user}{$ip}}); | |
791 | foreach my $method (sort $sort keys %{$Users{$user}{$ip}}) { | |
792 | my $val = $Users{$user}{$ip}{$method}; | |
793 | print " $method: " . timesplural($val); | |
794 | } | |
676 | 795 | } |
677 | 796 | } else { |
678 | my $val = (values %{$Users{$user}{$ip}})[0]; | |
679 | my $plural = ($val > 1) ? "s" : ""; | |
680 | print " $name: $val time$plural\n"; | |
797 | my $totalSort = TotalCountOrder(%Methods); | |
798 | foreach my $method (sort $totalSort keys %Methods) { | |
799 | print " $method:\n"; | |
800 | my $sort = CountOrder(%{$Methods{$method}}); | |
801 | foreach my $ip (sort $sort keys %{$Methods{$method}}) { | |
802 | my $name = LookupIP($ip); | |
803 | my $val = (values %{$Users{$user}{$ip}})[0]; | |
804 | print " $name: " . timesplural($val); | |
805 | } | |
806 | } | |
681 | 807 | } |
682 | 808 | } |
683 | 809 | } |
684 | 810 | } |
685 | 811 | |
686 | 812 | if (keys %RefusedAuthentication) { |
687 | print "\n\nAuthentication refused:\n"; | |
813 | print "\nAuthentication refused:\n"; | |
688 | 814 | foreach my $Reason (sort {$a cmp $b} keys %RefusedAuthentication) { |
689 | print " $Reason : $RefusedAuthentication{$Reason} Time(s)\n"; | |
815 | print " $Reason : " . timesplural($RefusedAuthentication{$Reason}); | |
690 | 816 | } |
691 | 817 | } |
692 | 818 | |
693 | 819 | if (keys %KrbAutFail) { |
694 | 820 | print "\n\Failed pam_krb5 authentication:\n"; |
695 | 821 | foreach my $User (sort keys %KrbAutFail) { |
696 | print " $User: " . $KrbAutFail{$User} . " Time(s)\n"; | |
822 | print " $User: " . timesplural($KrbAutFail{$User}); | |
697 | 823 | } |
698 | 824 | } |
699 | 825 | |
700 | 826 | if (keys %KrbAutErr) { |
701 | 827 | print "\n\pam_krb5 authentication errors:\n"; |
702 | 828 | foreach my $Error (sort keys %KrbAutErr) { |
703 | print " $Error: " . $KrbAutErr{$Error} . " Time(s)\n"; | |
829 | print " $Error: " . timesplural($KrbAutErr{$Error}); | |
704 | 830 | } |
705 | 831 | } |
706 | 832 | |
708 | 834 | if (keys %KrbErr) { |
709 | 835 | print "\n pam_krb5 errors:\n"; |
710 | 836 | foreach my $Error (sort keys %KrbErr) { |
711 | print " $Error: " . $KrbErr{$Error} . " Time(s)\n"; | |
837 | print " $Error: " . timesplural($KrbErr{$Error}); | |
712 | 838 | } |
713 | 839 | } |
714 | 840 | |
715 | 841 | |
716 | 842 | if (keys %DisconnectReceived) { |
717 | print "\n\nReceived disconnect:\n"; | |
843 | print "\nReceived disconnect:\n"; | |
718 | 844 | foreach my $Reason (sort {$a cmp $b} keys %DisconnectReceived) { |
719 | 845 | my $Total = 0; |
720 | 846 | print " $Reason"; |
727 | 853 | if( $Detail > 0 ) { |
728 | 854 | print "\n"; |
729 | 855 | } else { |
730 | print " : $Total Time(s)\n"; | |
856 | print " : " . timesplural($Total); | |
731 | 857 | } |
732 | 858 | } |
733 | 859 | } |
743 | 869 | my $output; |
744 | 870 | foreach my $badguy (sort {$a cmp $b} keys %RefusedConnections ) { |
745 | 871 | if ($RefusedConnectionsThreshold == 0 || $Detail > 5 || $RefusedConnections{$badguy} >= $RefusedConnectionsThreshold) { |
746 | $output .= " $badguy: " . $RefusedConnections{$badguy} . " Time(s)\n"; | |
872 | $output .= " $badguy: " . timesplural($RefusedConnections{$badguy}); | |
747 | 873 | } |
748 | 874 | } |
749 | 875 | if ($output ne '') { |
755 | 881 | if (keys %PamReleaseFail) { |
756 | 882 | print "\nCannot release PAM authentication:\n"; |
757 | 883 | foreach my $Error (sort {$a cmp $b} keys %PamReleaseFail) { |
758 | print " $Error : $PamReleaseFail{$Error} Time(s)\n"; | |
884 | print " $Error : " . timesplural($PamReleaseFail{$Error}); | |
759 | 885 | } |
760 | 886 | } |
761 | 887 | |
762 | 888 | if (keys %ShadowInfo) { |
763 | 889 | print "\nCould not get shadow information for:\n"; |
764 | 890 | foreach my $Error (sort {$a cmp $b} keys %ShadowInfo) { |
765 | print " $Error : $ShadowInfo{$Error} Time(s)\n"; | |
891 | print " $Error : " . timesplural($ShadowInfo{$Error}); | |
766 | 892 | } |
767 | 893 | } |
768 | 894 | |
769 | 895 | if (keys %PamError) { |
770 | 896 | print "\nError in PAM authentication:\n"; |
771 | 897 | foreach my $Error (sort {$a cmp $b} keys %PamError) { |
772 | print " $Error : $PamError{$Error} Time(s)\n"; | |
898 | print " $Error : " . timesplural($PamError{$Error}); | |
773 | 899 | } |
774 | 900 | } |
775 | 901 | |
776 | 902 | if (keys %PamChroot) { |
777 | 903 | print "\nPAM chroot:\n"; |
778 | 904 | foreach my $Reason (sort {$a cmp $b} keys %PamChroot) { |
779 | print " $Reason : $PamChroot{$Reason} Time(s)\n"; | |
905 | print " $Reason : " . timesplural($PamChroot{$Reason}); | |
780 | 906 | } |
781 | 907 | } |
782 | 908 | |
783 | 909 | if (keys %TTYModesFail) { |
784 | 910 | print "\nSetting tty modes failed:\n"; |
785 | 911 | foreach my $Reason (sort {$a cmp $b} keys %TTYModesFail) { |
786 | print " $Reason : $TTYModesFail{$Reason} Time(s)\n"; | |
912 | print " $Reason : " . timesplural($TTYModesFail{$Reason}); | |
787 | 913 | } |
788 | 914 | } |
789 | 915 | |
790 | 916 | if ($sftpRequests > 0) { |
791 | 917 | print "\nSFTP subsystem requests: $sftpRequests Time(s)\n"; |
918 | if ($Detail >= 50) { | |
919 | foreach my $root (sort {$a cmp $b} keys %Chroot) { | |
920 | print " Chroot: $root : " . timesplural($Chroot{$root}); | |
921 | } | |
922 | } | |
923 | if ($Detail >= 0) { | |
924 | foreach my $dir (sort {$a cmp $b} keys %CloseDir) { | |
925 | if ($CloseDir{$dir} != $OpenDir{$dir} || $Detail >= 40) { | |
926 | print " Directory $dir: opened/closed $OpenDir{$dir}/$CloseDir{$dir} Time(s)\n"; | |
927 | # Note: this number might not match if the open/closes span log windows..." | |
928 | } | |
929 | } | |
930 | } | |
931 | if ($Detail >= 30) { | |
932 | foreach my $details (sort {$a cmp $b} keys %CloseFileReadWrite) { | |
933 | if (my ($file,$read,$written) = ($details =~ /^(.*),(\d+),(\d+)$/)) { | |
934 | if ($read || $written || $Detail >= 40) { | |
935 | print " Read/Wrote $read/$written byte(s) from file $file\n"; | |
936 | } | |
937 | } | |
938 | } | |
939 | } | |
940 | if ($Detail >= 60) { | |
941 | foreach my $details (sort {$a cmp $b} keys %OpenFile) { | |
942 | if (my ($file,$flags,$mode) = ($details =~ /^(.*):([^:]*):(\d+)$/)) { | |
943 | print " Opened (mode: $mode, flags: $flags) file $file\n"; | |
944 | } | |
945 | } | |
946 | } | |
947 | if ($Detail >= 70) { | |
948 | foreach my $path (sort {$a cmp $b} keys %RealPath) { | |
949 | print " Realpath $path\n"; | |
950 | } | |
951 | } | |
952 | if ($Detail >= 50) { | |
953 | foreach my $details (sort {$a cmp $b} keys %SetModtime) { | |
954 | if (my ($modtime,$file) = ($details =~ /^([^,]*),(.*)$/)) { | |
955 | print " Set modtime $modtime for file $file\n"; | |
956 | } | |
957 | } | |
958 | } | |
959 | if ($Detail >= 70) { | |
960 | foreach my $path (sort {$a cmp $b} keys %Stat) { | |
961 | print " Stat: $path : " . timesplural($Stat{$path}); | |
962 | } | |
963 | } | |
964 | if ($Detail >= 40) { | |
965 | if ($StatusNoSuchFile) { | |
966 | print " Sent status No such file: " . timesplural($StatusNoSuchFile); | |
967 | } | |
968 | } | |
969 | if ($Detail >= 0) { | |
970 | if ($BytesSent || $BytesReceived) { | |
971 | print " Transferred: sent/received $BytesSent/$BytesReceived byte(s)\n"; | |
972 | } | |
973 | } | |
974 | if ($Detail >= 50) { | |
975 | foreach my $client (sort {$a cmp $b} keys %ClientVers) { | |
976 | print " Client version $client connected " . timesplural($ClientVers{$client}); | |
977 | } | |
978 | } | |
792 | 979 | } |
793 | 980 | |
794 | 981 | if (keys %ChmodErr) { |
795 | 982 | print "\nChmod errors:\n"; |
796 | foreach (keys %ChmodErr) { | |
983 | foreach (sort keys %ChmodErr) { | |
797 | 984 | my ($File,$Perm,$Why)= split ","; |
798 | print " " . $File . " " . $Perm . " failed(" . $Why . "): ". $ChmodErr{"$File,$Perm,$Why"} . " Time(s)\n"; | |
985 | print " " . $File . " " . $Perm . " failed(" . $Why . "): " . timesplural($ChmodErr{"$File,$Perm,$Why"}); | |
799 | 986 | } |
800 | 987 | } |
801 | 988 | |
803 | 990 | print "\nChown errors:\n"; |
804 | 991 | foreach (keys %ChownErr) { |
805 | 992 | my ($File,$From,$To,$Why)= split ","; |
806 | print " " . $File . " " . $From . " " .$To . " failed(" . $Why . "): ". $ChmodErr{"$File,$From,$To,$Why"} . " Time(s)\n"; | |
993 | print " " . $File . " " . $From . " " .$To . " failed(" . $Why . "): " . timesplural($ChmodErr{"$File,$From,$To,$Why"}); | |
807 | 994 | } |
808 | 995 | } |
809 | 996 | |
810 | if ( ($Detail == 7 && keys %Krb_relm > 1) || ($Detail > 8 && keys %Krb_relm) ){ | |
811 | print "\nSucessfull Kerberos Authentication from ",(scalar keys %Krb_relm)," relm:\n"; | |
812 | foreach my $relm (keys %Krb_relm) { | |
997 | if ( ($Detail == 7 && keys %Krb_realm > 1) || ($Detail > 8 && keys %Krb_realm) ){ | |
998 | print "\nSuccessful Kerberos Authentication from ",(scalar keys %Krb_realm)," realm:\n"; | |
999 | foreach my $realm (sort keys %Krb_realm) { | |
813 | 1000 | if($Detail > 9){ |
814 | print " ",$relm,":\n"; | |
815 | foreach my $user(keys %{$Krb_relm{$relm}}){ | |
816 | print " ",$user,": ". $Krb_relm{$relm}{$user} . " Times(s)\n"; | |
1001 | print " ",$realm,":\n"; | |
1002 | foreach my $user(sort keys %{$Krb_realm{$realm}}){ | |
1003 | print " ",$user,": " . timesplural($Krb_realm{$realm}{$user}); | |
817 | 1004 | } |
818 | 1005 | }else{ |
819 | print " ",$relm,": ". (scalar keys %{$Krb_relm{$relm}}) . " User(s)\n"; | |
1006 | print " ",$realm,": ". (scalar keys %{$Krb_realm{$realm}}) . " User(s)\n"; | |
820 | 1007 | } |
821 | 1008 | } |
822 | 1009 | } |
823 | 1010 | |
824 | 1011 | if (keys %OtherList) { |
825 | 1012 | print "\n**Unmatched Entries**\n"; |
826 | print "$_ : $OtherList{$_} time(s)\n" foreach keys %OtherList; | |
1013 | print "$_ : " . timesplural($OtherList{$_}) foreach sort keys %OtherList; | |
827 | 1014 | } |
828 | 1015 | |
829 | 1016 | exit(0); |
16 | 16 | use strict; |
17 | 17 | my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0; |
18 | 18 | my %Errors; |
19 | my $Service; | |
19 | 20 | my %Starts; |
20 | 21 | my %Stops; |
21 | 22 | my %OtherList; |
23 | 24 | # Lines are of the form: |
24 | 25 | # sssd[service]: |
25 | 26 | while (defined(my $ThisLine = <STDIN>)) { |
27 | next unless $ThisLine =~ /^sssd/; | |
26 | 28 | chomp($ThisLine); |
27 | 29 | |
28 | # Strip off and record the service, set to Daemon if none | |
29 | $ThisLine =~ s/sssd\[([^:]+)\]: //; | |
30 | my $Service = defined($1) ? $1 : "Daemon"; | |
30 | # Strip off leading sssd: | |
31 | $ThisLine =~ s/^sssd: //; | |
32 | ||
33 | # Remove []s from debug messages if any | |
34 | $ThisLine =~ s/^\[(\S+)\] /$1 /; | |
35 | $ThisLine =~ s/^\[(\S+)\] /$1 /; | |
36 | ||
37 | # Remove pids from debug messages if any | |
38 | $ThisLine =~ s/\[\d+\]//; | |
39 | ||
40 | # Default service | |
41 | $Service = "Daemon"; | |
42 | ||
43 | # Strip off and record the service if any | |
44 | if ($ThisLine =~ s/^sssd\[(\S+)\]:? // or $ThisLine =~ s/^sssd_([^:]+): //) { | |
45 | $Service = $1; | |
46 | } | |
31 | 47 | |
32 | 48 | if ($ThisLine =~ /^Starting up/) { |
33 | 49 | $Starts{$Service}++; |
56 | 56 | my $CmdsThresh = $ENV{'command_run_threshold'} || 0; |
57 | 57 | my %IgnoreCmds; |
58 | 58 | |
59 | my ($user, $error, $tty, $dir, $euser, $cmd, $args); | |
59 | my ($user, $error, $tty, $dir, $euser, $egroup, $cmd, $args); | |
60 | 60 | my (%ConFailed); |
61 | 61 | my $contlines = 0; |
62 | 62 | my $argsprinted = 0; |
83 | 83 | # Ignore |
84 | 84 | } elsif ($ThisLine =~ /(.+): conversation failed/) { |
85 | 85 | $ConFailed{$1}++; |
86 | } elsif ( ($user, $error, $tty, $dir, $euser, $cmd, $args) = $ThisLine =~ m/^\s*(\S+) : (.*; )?TTY=(\S+) ; PWD=(.*?) ; USER=(\S+) ; COMMAND=(\S+)( ?.*)/) { | |
86 | } elsif ( ($user, $error, $tty, $dir, $euser, $egroup, $cmd, $args) = $ThisLine =~ m/^\s*(\S+) : (.*; )?TTY=(\S+) ; PWD=(.*?) ; USER=(\S+) ;(?: GROUP=(\S+) ;)? COMMAND=(\S+)( ?.*)/) { | |
87 | 87 | next if (defined($IgnoreCmds{$user}{$euser}) && $cmd =~ join("|",@{$IgnoreCmds{$user}{$euser}})); |
88 | 88 | next if (defined($IgnoreCmds{'any'}{$euser}) && $cmd =~ join("|",@{$IgnoreCmds{'any'}{$euser}})); |
89 | next if (defined($IgnoreCmds{$user}{'any'}) && $cmd =~ join("|",@{$IgnoreCmds{$user}{'any'}})); | |
90 | if ($egroup) { | |
91 | $euser .= ":${egroup}"; | |
92 | } | |
89 | 93 | push @{$byUser{$user}{$euser}}, [$error . $cmd, $args, $dir, $tty]; |
90 | 94 | $byUserSum{$user}{$euser}{$cmd} += 1; |
91 | 95 | } elsif ( ($user,$euser) = $ThisLine =~ /^\s*(\S+) : no passwd entry for (\S+)\!$/) { |
15 | 15 | |
16 | 16 | use strict; |
17 | 17 | my $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'} || 0; |
18 | my $Ignore_failed = $ENV{'ignore_failed'} || ""; | |
19 | my %ConfigError; | |
18 | 20 | my %Activated; |
19 | 21 | my %Failed; |
22 | my %Deactivated; | |
20 | 23 | my $Reexecuted = 0; |
21 | 24 | my %Reloaded; |
22 | 25 | my %Slice; |
26 | my %Slow; | |
23 | 27 | my %Started; |
24 | 28 | my %Target; |
25 | 29 | my $TimeChanged = 0; |
27 | 31 | my %UserSession; |
28 | 32 | my %OtherList; |
29 | 33 | |
30 | # Failue will generate multiple messages like: | |
34 | # Failure will generate multiple messages like: | |
31 | 35 | # Feb 5 16:37:50 hostname systemd: ansible-pull.service: main process exited, code=exited, status=2/INVALIDARGUMENT |
32 | 36 | # Feb 5 16:37:50 hostname systemd: Failed to start Run ansible-pull on boot. |
33 | 37 | # Feb 5 16:37:50 hostname systemd: Unit ansible-pull.service entered failed state. |
35 | 39 | |
36 | 40 | while (defined(my $ThisLine = <STDIN>)) { |
37 | 41 | chomp($ThisLine); |
38 | if ($ThisLine =~ /^(Activating|Deactivating|Mounting|Unmounting|Starting|Stopping) / or | |
42 | if ($ThisLine =~ /^(Activat|Deactivat|Mount|Unmount|Reload|Start|Stopp)ing / or | |
39 | 43 | # These events will be caught with the Unit X entered failed state message |
40 | 44 | $ThisLine =~ /^Failed to start / or |
45 | $ThisLine =~ /: Failed with result / or | |
41 | 46 | $ThisLine =~ / failed\.$/ or |
42 | $ThisLine =~ /: (control|main) process exited, code=(exited|killed),? status=/ or | |
47 | $ThisLine =~ /([Cc]ontrol|[Mm]ain|[Mm]ount) process exited, code=(exited|killed|dumped),? status=/ or | |
43 | 48 | # Informational |
44 | $ThisLine =~ /^Closed .* [Ss]ocket\.$/ or | |
49 | $ThisLine =~ /^Closed .* [Ss]ockets?\.$/ or | |
50 | $ThisLine =~ /^Closed .* [Ss]cheduler\.$/ or | |
51 | $ThisLine =~ /^Closed .* [Ww]atch\.$/ or | |
45 | 52 | $ThisLine =~ /^Closed udev / or |
53 | $ThisLine =~ /^Received SIGINT\./ or | |
46 | 54 | $ThisLine =~ /^Deactivated / or |
47 | 55 | $ThisLine =~ /^Detected (architecture|virtualization) / or |
48 | 56 | $ThisLine =~ /^Found device / or |
49 | $ThisLine =~ /^Got automount request for \/proc\// or | |
57 | $ThisLine =~ /Got automount request for \/proc\// or | |
50 | 58 | $ThisLine =~ /^Inserted module / or |
51 | 59 | $ThisLine =~ /^Listening on / or |
52 | 60 | $ThisLine =~ /^Mounted / or |
53 | 61 | $ThisLine =~ /^Relabelled / or |
54 | 62 | $ThisLine =~ /^Reloading\.$/ or # Happens on each boot at switch root |
63 | $ThisLine =~ /^RTC configured in / or | |
55 | 64 | $ThisLine =~ /^Running in initial RAM disk\.$/ or |
56 | 65 | $ThisLine =~ /^Set hostname to / or |
57 | 66 | $ThisLine =~ /^Shutting down\.$/ or |
60 | 69 | $ThisLine =~ /^Switching root\.$/ or |
61 | 70 | $ThisLine =~ /^Successfully loaded SELinux policy in / or |
62 | 71 | $ThisLine =~ /: Supervising process .* which is not our child\. We'll most likely not notice when it exits\.$/ or |
72 | $ThisLine =~ /: Got notification message from PID \d+, but reception is disabled\./ or | |
73 | $ThisLine =~ /: Got notification message from PID \d+, but reception only permitted for main PID \d+/ or | |
63 | 74 | $ThisLine =~ /^systemd (\d+) running in system mode/ or |
75 | $ThisLine =~ /Transaction is destructive\./ or | |
64 | 76 | $ThisLine =~ /^Unit .* is bound to inactive unit .*\. Stopping, too\./ or |
65 | $ThisLine =~ /^Unit .* is not needed anymore\. Stopping\./ or | |
77 | $ThisLine =~ /Unit (.* is )?not needed anymore\. Stopping\./ or | |
78 | $ThisLine =~ /State '(stop-sigterm|stop-final-sigterm)' timed out\. Killing\./ or | |
79 | $ThisLine =~ /Stopping timed out\. Killing\./ or | |
80 | $ThisLine =~ /Processes still around after .*SIGKILL\./ or | |
66 | 81 | $ThisLine =~ /^Unmounted / or |
82 | $ThisLine =~ /[Hh]ardware watchdog / or | |
83 | $ThisLine =~ /PID file .* not readable \(yet\?\) after start/ or | |
67 | 84 | # Units can depend on files that do not exist |
68 | $ThisLine =~ /^Cannot add dependency job for unit .*, ignoring: Unit .* failed to load: No such file or directory\.$/ or | |
85 | $ThisLine =~ /Cannot add dependency job(:? for unit .*)?, ignoring: Unit (:?.* failed to load: No such file or directory|not found)\.$/ or | |
69 | 86 | # https://bugs.freedesktop.org/show_bug.cgi?id=90386 |
70 | $ThisLine =~ /^Device .* appeared twice with different sysfs paths .* and / or | |
87 | $ThisLine =~ /Dev(ice)? .* appeared twice with different sysfs paths .* and / or | |
71 | 88 | # Inactive units are sometimes reloaded |
72 | 89 | $ThisLine =~ /^Unit .* cannot be reloaded because it is inactive\.$/ or |
73 | # https://bugzilla.redhat.com/show_bug.cgi?id=1293941 | |
74 | $ThisLine =~ /^Configuration file \/usr\/lib\/systemd\/system\/auditd\.service is marked world-inaccessible/ or | |
75 | # https://bugzilla.redhat.com/show_bug.cgi?id=1301182 | |
76 | $ThisLine =~ /^Configuration file \/usr\/lib\/systemd\/system\/wpa_supplicant\.service is marked executable/ or | |
90 | $ThisLine =~ /^.*: Unit cannot be reloaded because it is inactive\.$/ or | |
77 | 91 | # https://bugzilla.redhat.com/show_bug.cgi?id=1306452 |
78 | $ThisLine =~ /^tmp\.mount: Directory \/tmp to mount over is not empty, mounting anyway\.$/ or | |
92 | $ThisLine =~ /^[^ ]*\.mount: Directory \/[^ ]* to mount over is not empty, mounting anyway\.$/ or | |
93 | # A known issue - reported by multiple distributions | |
94 | $ThisLine =~ /^user\@\d+\.service: Failed at step CGROUP spawning \/usr\/lib\/systemd\/systemd: No such file or directory$/ or | |
79 | 95 | $ThisLine =~ /^Received SIGRTMIN\+2[01] from PID \d+ \(plymouthd\)\.$/ or |
80 | 96 | # https://bugzilla.redhat.com/show_bug.cgi?id=1072368 |
81 | 97 | $ThisLine =~ /^Received SIGRTMIN\+24 from PID \d+ \(kill\)\.$/ or |
82 | 98 | $ThisLine =~ /^Removed slice / or |
83 | 99 | $ThisLine =~ /^pam_unix\(systemd-user:session\): session (?:opened|closed) for user/ or |
84 | $ThisLine =~ /Adding .* random time\.$/ | |
100 | $ThisLine =~ /Adding .* random time\.$/ or | |
101 | # These happen on every shutdown - downgraded to debug message in systemd v235 | |
102 | # https://github.com/systemd/systemd/issues/6777 | |
103 | $ThisLine =~ /^Failed to propagate agent release message: (?:Connection reset by peer|Transport endpoint is not connected)/ or | |
104 | $ThisLine =~ /^cgroup compatibility translation between legacy and unified hierarchy settings activated\. See cgroup-compat debug messages for details\.$/ or | |
105 | $ThisLine =~ /^.*\.socket: Socket service .* already active/ | |
85 | 106 | ) { |
86 | 107 | # Ignore these |
108 | } elsif (my ($service,$reason) = ($ThisLine =~ /^Configuration file ([^ ]*) is ([^.]*)\./)) { | |
109 | $ConfigError{$reason}{$service}++; | |
110 | } elsif (my ($service,$reason) = ($ThisLine =~ /^\[(.*)\] (Support for option .* has been removed) and it is ignored/)) { | |
111 | $ConfigError{$reason}{$service}++; | |
87 | 112 | } elsif (my ($service) = ($ThisLine =~ /^Unit (.*) entered failed state\.$/)) { |
113 | $Failed{$service}++; | |
114 | } elsif (my ($service) = ($ThisLine =~ /^(.*): Unit entered failed state\.$/)) { | |
115 | $Failed{$service}++; | |
116 | } elsif (my ($service) = ($ThisLine =~ /^(.*) failed with error code \d+\.$/)) { | |
117 | $Failed{$service}++; | |
118 | } elsif (my ($service) = ($ThisLine =~ /^Failed (unmounting .*)\.$/)) { | |
119 | $Failed{$service}++; | |
120 | } elsif (my ($service) = ($ThisLine =~ /^Failed to (listen on .*)\.$/)) { | |
88 | 121 | $Failed{$service}++; |
89 | 122 | } elsif (my ($target) = ($ThisLine =~ /^Reached target (.*)\.$/)) { |
90 | 123 | $Target{$target}++; |
97 | 130 | $Started{$service}++; |
98 | 131 | } elsif (my ($service) = ($ThisLine =~ /^Reloaded (.*)\.$/)) { |
99 | 132 | $Reloaded{$service}++; |
133 | } elsif (my ($service) = ($ThisLine =~ /^Deactivated (.*)\.$/)) { | |
134 | $Deactivated{$service}++; | |
100 | 135 | } elsif ($ThisLine eq "Reexecuting.") { |
101 | 136 | $Reexecuted++; |
102 | 137 | } elsif ($ThisLine =~ /^Time has been changed$/) { |
103 | 138 | $TimeChanged++; |
104 | 139 | } elsif (my ($slice) = ($ThisLine =~ /^Created slice (.*)\.$/)) { |
105 | 140 | $Slice{$slice}++; |
141 | } elsif (my ($pidfile) = ($ThisLine =~ /^PID file (.*) not readable \(yet\?\) after start\.$/)) { | |
142 | $Slow{$pidfile}++; | |
106 | 143 | } else { |
107 | 144 | $OtherList{$ThisLine}++; |
108 | 145 | } |
146 | } | |
147 | ||
148 | if (keys %ConfigError) { | |
149 | print "Configuration errors:\n"; | |
150 | foreach my $reason (sort {$a cmp $b} keys %ConfigError) { | |
151 | my $tot = 0; | |
152 | print " $reason"; | |
153 | foreach my $service (sort {$a cmp $b} keys %{$ConfigError{$reason}}) { | |
154 | $tot += $ConfigError{$reason}{$service}; | |
155 | if ($Detail >= 10) { | |
156 | print "\n $service: $ConfigError{$reason}{$service} Time(s)"; | |
157 | } | |
158 | } | |
159 | if ($Detail < 10) { | |
160 | print ": $tot Time(s)" | |
161 | } | |
162 | print "\n"; | |
163 | } | |
164 | print "\n"; | |
165 | } | |
166 | ||
167 | # Because we set Failed in multiple locations, cleanup once here | |
168 | foreach my $item (keys %Failed) { | |
169 | delete $Failed{$item} if ($item =~ /^$Ignore_failed$/i); | |
109 | 170 | } |
110 | 171 | |
111 | 172 | if (keys %Failed) { |
149 | 210 | print "\n"; |
150 | 211 | } |
151 | 212 | |
213 | if (keys %Slow && $Detail > 3) { | |
214 | print "Slow to start:\n"; | |
215 | foreach my $pidfile (sort {$a cmp $b} keys %Slow) { | |
216 | print " $pidfile: $Slow{$pidfile} Time(s)\n"; | |
217 | } | |
218 | print "\n"; | |
219 | } | |
220 | ||
152 | 221 | if (keys %Reloaded && $Detail > 5) { |
153 | 222 | print "Reloaded:\n"; |
154 | 223 | foreach my $item (sort {$a cmp $b} keys %Reloaded) { |
155 | 224 | print " $item: $Reloaded{$item} Time(s)\n"; |
225 | } | |
226 | print "\n"; | |
227 | } | |
228 | ||
229 | if (keys %Deactivated && $Detail > 5) { | |
230 | print "Deactivated:\n"; | |
231 | foreach my $item (sort {$a cmp $b} keys %Deactivated) { | |
232 | print " $item: $Deactivated{$item} Time(s)\n"; | |
156 | 233 | } |
157 | 234 | print "\n"; |
158 | 235 | } |
93 | 93 | foreach my $host ( sort keys %isdn ) { |
94 | 94 | print "\nISDN on $host:\n"; |
95 | 95 | foreach my $number ( sort keys %{$isdn{$host}} ) { |
96 | print "Number: $number dailed total $isdn{$host}->{$number}->{'seconds'} seconds"; | |
96 | print "Number: $number dialed total $isdn{$host}->{$number}->{'seconds'} seconds"; | |
97 | 97 | if ($isdn{$host}->{$number}->{'start'}) { |
98 | 98 | print " started $isdn{$host}->{$number}->{'start'} times\n"; |
99 | 99 | } else { |
104 | 104 | } |
105 | 105 | |
106 | 106 | if ($RHNRegistration) { |
107 | print "\nSystem registred to rhn " . $RHNRegistration . " time(s)\n"; | |
107 | print "\nSystem registered to rhn " . $RHNRegistration . " time(s)\n"; | |
108 | 108 | } |
109 | 109 | |
110 | 110 | if ($#OtherList >= 0) { |
18 | 18 | my $SearchDate = TimeFilter('%a %b %e %H:%M:%S %Y'); |
19 | 19 | |
20 | 20 | $Detail = $ENV{'LOGWATCH_DETAIL_LEVEL'}; |
21 | $IgnoreUnmatched = $ENV{'vsftpd_ignore_unmatched'}; | |
21 | $IgnoreUnmatched = $ENV{'vsftpd_ignore_unmatched'} || 0; | |
22 | $IgnoreRobots = $ENV{'vsftpd_ignore_robots'} || 0; | |
22 | 23 | $TotalBytesOut = 0; |
23 | 24 | $TotalBytesIn = 0; |
24 | 25 | $TotalDeleted = 0; |
53 | 54 | $TotalBytesIn+= $FileSize; |
54 | 55 | push @FailedUploadedFiles,$Temp; |
55 | 56 | } elsif ( ($User,$IP,$FileName,$FileSize) = ( $ThisLine =~ /(?:\[.*\] )?\[(.*)\] OK DOWNLOAD: Client \"(.*)\", \"(.*)\", (?:(\d+) bytes)?/ ) ) { |
57 | next if $FileName eq "robots.txt" and $IgnoreRobots; | |
56 | 58 | $Temp = " " . $FileName . " -> " . $IP . " (User: " . $User . ")\n"; |
57 | 59 | $TotalBytesOut+= $FileSize; |
58 | 60 | push @DownloadedFiles,$Temp; |
150 | 152 | |
151 | 153 | if ( ( $#DownloadedFiles >= 0 ) or |
152 | 154 | ( $#FailedDownloadedFiles >=0 ) ) { |
153 | if ( $#DownloadedFiles >= 0) { | |
155 | if ( $Detail and $#DownloadedFiles >= 0) { | |
154 | 156 | print "\nOutgoing FTP Files:\n"; |
155 | 157 | print @DownloadedFiles; |
156 | 158 | } |
158 | 160 | print "\nFailed Downloads\n"; |
159 | 161 | print @FailedDownloadedFiles; |
160 | 162 | } |
161 | print "\nTOTAL KB OUT: " . $TotalKBytesOut . "KB (" . $TotalMBytesOut . "MB)\n"; | |
163 | if ( $Detail or $#FailedDownloadedFiles >= 0) { | |
164 | print "\nTOTAL KB OUT: " . $TotalKBytesOut . "KB (" . $TotalMBytesOut . "MB)\n"; | |
165 | } | |
162 | 166 | } |
163 | 167 | |
164 | 168 | if ( $Detail > 5 ) { |
16 | 16 | ########################################################################## |
17 | 17 | # This is a logwatch script that looks at a log file composed of windows auth |
18 | 18 | # security logs counts the number of times a user failed to login and |
19 | # optionally the number times they succesfully logged in and some other account | |
19 | # optionally the number times they successfully logged in and some other account | |
20 | 20 | # creation/modification audits. |
21 | 21 | # |
22 | 22 | # See the following sites for event id documentation: |
99 | 99 | # $logonFailure{$1}{$2}{$3}++; |
100 | 100 | #} |
101 | 101 | |
102 | elsif ($eventid == 861) { # The Windows Firewall has detected an application listenin for incomming traffic. | |
102 | elsif ($eventid == 861) { # The Windows Firewall has detected an application listenin for incoming traffic. | |
103 | 103 | $msg =~ /Path:\s*(\S+)\s+.+User account:\s*(\S+)\s+.+IP protocol:(\S+)\s+Port number:\s*(\S+)\s+Allowed:\s*(\S+)/; |
104 | 104 | #print "DEBUG Server Application Firewalled: path:$1 account:$2 port:$3 $4 allowed:$5\n"; |
105 | 105 | $firewall{$host}{$2}{$1}{$3}{$4}{$5}++; |
245 | 245 | printLevel2("Windows Failed Logins by Account, Host", \%loginFailByAccount); |
246 | 246 | } |
247 | 247 | if (keys %loginFailByHost) { |
248 | printLevel2("Windwos Failed Logins by Host, Account", \%loginFailByHost); | |
248 | printLevel2("Windows Failed Logins by Host, Account", \%loginFailByHost); | |
249 | 249 | } |
250 | 250 | |
251 | 251 | if (keys %krbAuthFailByAccount) { |
79 | 79 | ($ThisLine =~ /Listening on interface .* Disabled/) or |
80 | 80 | ($ThisLine =~ /Listen and drop on /) or |
81 | 81 | ($ThisLine =~ /Listening on routing socket on/) or |
82 | ($ThisLine =~ /.* interface .* -> \(null\)/) or | |
82 | ($ThisLine =~ /.* interface .* -> .*/) or | |
83 | 83 | ($ThisLine =~ /Deferring DNS for/) or |
84 | 84 | ($ThisLine =~ /ntp_io: estimated max descriptors: \d*, initial socket boundary: \d*/) or |
85 | 85 | ($ThisLine =~ /peers refreshed$/) or |
86 | 86 | ($ThisLine =~ /restrict: error in address/) or |
87 | ($ThisLine =~ /syntax error in .+ line \d+, column \d+$/) | |
87 | ($ThisLine =~ /syntax error in .+ line \d+, column \d+$/) or | |
88 | ($ThisLine =~ /Listen normally on /) or | |
89 | ($ThisLine =~ /the NTP socket is in use, exiting/) or | |
90 | 0 # This line prevents blame shifting as lines are added above | |
88 | 91 | ) { |
89 | 92 | # Ignore these |
90 | 93 | } elsif ($ThisLine =~ m/ntpd [\d\-\.\w@]+ ... ... .. ..:..:.. /) { |
28 | 28 | my $show_mail_dir_sizes = $ENV{'show_mail_dir_sizes'} || 0; |
29 | 29 | my $mail_dir = $ENV{'mail_dir'} || 0; |
30 | 30 | my $show_disk_usage = $ENV{'show_disk_usage'} || 0; |
31 | my $diskfull_threshhold = $ENV{'diskfull_threshold'} || 90; | |
31 | my $diskfull_threshold = $ENV{'diskfull_threshold'} || 90; | |
32 | 32 | my $diskfull_exclude_dirs = $ENV{'diskfull_exclude_dirs'} || '$'; |
33 | 33 | my $local_disks_only = $ENV{'local_disks_only'} || 0; |
34 | 34 | |
132 | 132 | my @fields = split(' ', $row); |
133 | 133 | my $use = $fields[4]; |
134 | 134 | $use =~ s/%//; |
135 | if (($use > $diskfull_threshhold) && | |
135 | if (($use > $diskfull_threshold) && | |
136 | 136 | ($fields[0] !~ /\/dev\/scd/ ) && |
137 | 137 | ($fields[0] !~ /\/dev\/sr/ ) && |
138 | 138 | ($fields[0] !~ /\/dev\/loop./) && |
139 | ($fields[5] !~ /^$diskfull_exclude_dirs/)) { | |
139 | ($fields[5] !~ /^$diskfull_exclude_dirs/i)) { | |
140 | 140 | print "$fields[5] ($fields[0]) => $fields[4] Used. Warning. Disk Filling up.\n"; |
141 | 141 | } |
142 | 142 | } |
203 | 203 | MailDirectorySizes($mail_dir); |
204 | 204 | } |
205 | 205 | |
206 | if ($diskfull_threshhold > 0) { | |
206 | if ($diskfull_threshold > 0) { | |
207 | 207 | DiskFull(); |
208 | 208 | } |
209 | 209 |
140 | 140 | while (<FILE1>) |
141 | 141 | { |
142 | 142 | if (/ipv(\d+)-forwarding .*default=(\S+) current=(\S+)/) { |
143 | print "IPv$1 fowarding is $3 (normal state is $2)\n"; | |
143 | print "IPv$1 forwarding is $3 (normal state is $2)\n"; | |
144 | 144 | } |
145 | 145 | } |
146 | 146 | close(FILE1) || die "can't close $!"; |
32 | 32 | # These scripts were created as part of the dnssec-tools project. |
33 | 33 | # For more information, see http://sourceforge.net/dnssec-tools. |
34 | 34 | # Detailed instructions for setting up BIND 9.3.* to use these logwatch |
35 | # configuration files and scripts are containted in the README file | |
35 | # configuration files and scripts are contained in the README file | |
36 | 36 | # on sourceforge. |
37 | 37 | ############################################################################# |
38 | 38 |
24 | 24 | # customize the Timefilter by appending a string: |
25 | 25 | # *ApplyStdDate = "%H:%M %d/%m/%Y" |
26 | 26 | $SearchDate = TimeFilter($ARGV[0] || '%b %e %H:%M:%S '); |
27 | $SearchDateRsyslog = TimeFilter('%Y-%m-%dT%H:%M:%S\.[0-9]+[+-][0-9]{2}:[0-9]{2} '); | |
27 | $SearchDateRsyslog = TimeFilter('%Y-%m-%dT%H:%M:%S(:?\.[0-9]+)?[+-][0-9]{2}:[0-9]{2} '); | |
28 | 28 | |
29 | 29 | # The date might be "Dec 09", but it needs to be "Dec 9"... |
30 | 30 | #$SearchDate =~ s/ 0/ /; |
39 | 39 | if ($ThisLine =~ m/^$SearchDate/o) { |
40 | 40 | print $ThisLine; |
41 | 41 | } elsif ($ThisLine =~ /^$SearchDateRsyslog/o) { |
42 | $ThisLine =~ s/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})\.[0-9]+[+-][0-9]{2}:[0-9]{2} //o; | |
42 | $ThisLine =~ s/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(:?\.[0-9]+)?[+-][0-9]{2}:[0-9]{2} //o; | |
43 | 43 | print POSIX::strftime("%b %e %H:%M:%S", $6, $5, $4, $3, $2-1, $1 - 1900) . " " . $ThisLine; |
44 | 44 | } elsif ($ThisLine =~ m/(Mon|Tue|Wed|Thu|Fri|Sat|Sun) $SearchDate\d{4}/o) { |
45 | 45 | print $ThisLine; |
2 | 2 | # $Id$ |
3 | 3 | ########################################################################## |
4 | 4 | |
5 | # This feature concieved by mark@winksmith.com | |
5 | # This feature conceived by mark@winksmith.com | |
6 | 6 | |
7 | 7 | ######################################################## |
8 | 8 | ## Copyright (c) 2008 Kirk Bauer |
19 | 19 | ## copyright please contact logwatch-devel@lists.sourceforge.net. |
20 | 20 | ######################################################### |
21 | 21 | |
22 | # This feature concieved by mark@winksmith.com | |
22 | # This feature conceived by mark@winksmith.com | |
23 | 23 | my $hostname = $ENV{'LOGWATCH_ONLY_HOSTNAME'}; |
24 | 24 | |
25 | 25 | #Clean hostname it could be a comma list from hostlimit |