Subversion Repositories vnag

Rev

Rev 36 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 36 Rev 59
1
<?php /* <ViaThinkSoftSignature>
1
<?php /* <ViaThinkSoftSignature>
2
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
23
Q==
23
A==
24
</ViaThinkSoftSignature> */ ?>
24
</ViaThinkSoftSignature> */ ?>
25
<?php
25
<?php
26
 
26
 
27
/*
27
/*
28
 * VNag - Nagios Framework for PHP
28
 * VNag - Nagios Framework for PHP
29
 * Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
29
 * Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com>
30
 * Licensed under the terms of the Apache 2.0 license
30
 * Licensed under the terms of the Apache 2.0 license
31
 *
31
 *
32
 * Revision 2018-11-03
32
 * Revision 2022-12-18
33
 *
33
 *
34
 * Changelog:
34
 * Changelog:
35
 * 2018-08-01   1.0   Initial release
35
 * 2018-08-01   1.0   Initial release
36
 * 2018-09-02   1.1   Added argument -e|--emptyok
36
 * 2018-09-02   1.1   Added argument -e|--emptyok
37
 *                    Output a warning if the Linux user does not exist.
37
 *                    Output a warning if the Linux user does not exist.
38
 * 2018-10-01   1.2   Fixed a bug where too many unnecessary requests were sent to ipinfo.io
38
 * 2018-10-01   1.2   Fixed a bug where too many unnecessary requests were sent to ipinfo.io
39
 *                    Cache file location ~/.last_ipcache is now preferred
39
 *                    Cache file location ~/.last_ipcache is now preferred
40
 *                    A token for ipinfo.io can now be provided
40
 *                    A token for ipinfo.io can now be provided
41
 * 2018-11-03   1.2.1 "system boot" lines are now excluded
41
 * 2018-11-03   1.2.1 "system boot" lines are now excluded
-
 
42
 * 2022-12-18   1.2.2 Use the new cache directory now
42
 */
43
 */
43
 
44
 
44
// QUE: should we allow usernames to have wildcards, regexes or comma separated?
45
// QUE: should we allow usernames to have wildcards, regexes or comma separated?
45
 
46
 
46
declare(ticks=1);
47
declare(ticks=1);
47
 
48
 
48
class LastCheck extends VNag {
49
class LastCheck extends VNag {
49
        private $argUser = null;
50
        private $argUser = null;
50
        private $argRegex = null;
51
        private $argRegex = null;
51
        private $argWtmpFiles = null;
52
        private $argWtmpFiles = null;
52
        private $argEmptyOk = null;
53
        private $argEmptyOk = null;
53
        private $argIpInfoToken = null;
54
        private $argIpInfoToken = null;
54
 
55
 
55
        private $cache = null;
56
        private $cache = null;
56
        private $cacheFile = null;
57
        private $cacheFile = null;
57
        private $cacheDirty = false;
58
        private $cacheDirty = false;
58
 
59
 
59
        protected function getIpCacheFile() {
-
 
60
                $homedir = @getenv('HOME');
-
 
61
                if ($homedir) {
-
 
62
                        $try = "${homedir}/.last_ipcache";
-
 
63
                        if (file_exists($try)) return $try;
-
 
64
                        if (@touch($try)) return $try;
-
 
65
                }
-
 
66
 
-
 
67
                $user = posix_getpwuid(posix_geteuid());
-
 
68
                if (isset($user['dir'])) {
-
 
69
                        $homedir = $user['dir'];
-
 
70
                        $try = "${homedir}/.last_ipcache";
-
 
71
                        if (file_exists($try)) return $try;
-
 
72
                        if (@touch($try)) return $try;
-
 
73
                }
-
 
74
 
-
 
75
                if (isset($user['name'])) {
-
 
76
                        $username = $user['name'];
-
 
77
                        $try = "/tmp/ipcache_${username}.tmp";
-
 
78
                        if (file_exists($try)) return $try;
-
 
79
                        if (@touch($try)) return $try;
-
 
80
                }
-
 
81
 
-
 
82
                return false; // should usually never happen
-
 
83
        }
-
 
84
 
-
 
85
        public function __construct() {
60
        public function __construct() {
86
                parent::__construct();
61
                parent::__construct();
87
 
62
 
88
                if ($this->is_http_mode()) {
63
                if ($this->is_http_mode()) {
89
                        // Don't allow the standard arguments via $_REQUEST
64
                        // Don't allow the standard arguments via $_REQUEST
90
                        $this->registerExpectedStandardArguments('');
65
                        $this->registerExpectedStandardArguments('');
91
                } else {
66
                } else {
92
                        $this->registerExpectedStandardArguments('Vhtv');
67
                        $this->registerExpectedStandardArguments('Vhtv');
93
                }
68
                }
94
 
69
 
95
                $this->addExpectedArgument($this->argUser = new VNagArgument('u', 'user', VNagArgument::VALUE_REQUIRED, 'user', 'The Linux username. If the argument is missing, all users will be checked.', null));
70
                $this->addExpectedArgument($this->argUser = new VNagArgument('u', 'user', VNagArgument::VALUE_REQUIRED, 'user', 'The Linux username. If the argument is missing, all users will be checked.', null));
96
                $this->addExpectedArgument($this->argRegex = new VNagArgument('R', 'regex', VNagArgument::VALUE_REQUIRED, 'regex', 'The regular expression (in PHP: preg_match) which is applied on IP, Hostname, Country, AS number or ISP name. If the regular expression matches, the login will be accepted, otherweise an alert will be triggered. Example: /DE/ismU or /Telekom/ismU', null));
71
                $this->addExpectedArgument($this->argRegex = new VNagArgument('R', 'regex', VNagArgument::VALUE_REQUIRED, 'regex', 'The regular expression (in PHP: preg_match) which is applied on IP, Hostname, Country, AS number or ISP name. If the regular expression matches, the login will be accepted, otherweise an alert will be triggered. Example: /DE/ismU or /Telekom/ismU', null));
97
                $this->addExpectedArgument($this->argWtmpFiles = new VNagArgument('f', 'wtmpfile', VNagArgument::VALUE_REQUIRED, 'wtmpfile', 'Filemask of the wtmp file (important if you use logrotate), e.g. \'/var/log/wtmp*\'', '/var/log/wtmp*'));
72
                $this->addExpectedArgument($this->argWtmpFiles = new VNagArgument('f', 'wtmpfile', VNagArgument::VALUE_REQUIRED, 'wtmpfile', 'Filemask of the wtmp file (important if you use logrotate), e.g. \'/var/log/wtmp*\'', '/var/log/wtmp*'));
98
                $this->addExpectedArgument($this->argEmptyOk = new VNagArgument('e', 'emptyok', VNagArgument::VALUE_FORBIDDEN, null, 'Treat an empty result (e.g. empty wtmp file after rotation) as success; otherwise treat it as status "Unknown"', null));
73
                $this->addExpectedArgument($this->argEmptyOk = new VNagArgument('e', 'emptyok', VNagArgument::VALUE_FORBIDDEN, null, 'Treat an empty result (e.g. empty wtmp file after rotation) as success; otherwise treat it as status "Unknown"', null));
99
                $this->addExpectedArgument($this->argIpInfoToken = new VNagArgument(null, 'ipInfoToken', VNagArgument::VALUE_REQUIRED, 'token', 'If you have a token for ipinfo.io, please enter it here. Without token, you can query the service approx 1,000 times per day (which should be enough)', null));
74
                $this->addExpectedArgument($this->argIpInfoToken = new VNagArgument(null, 'ipInfoToken', VNagArgument::VALUE_REQUIRED, 'token', 'If you have a token for ipinfo.io, please enter it here. Without token, you can query the service approx 1,000 times per day (which should be enough)', null));
100
 
75
 
101
                $this->getHelpManager()->setPluginName('vnag_last');
76
                $this->getHelpManager()->setPluginName('vnag_last');
102
                $this->getHelpManager()->setVersion('1.2');
77
                $this->getHelpManager()->setVersion('1.2');
103
                $this->getHelpManager()->setShortDescription('This plugin checks the logs of the tool "LAST" an warns when users have logged in with an unexpected IP/Country/ISP.');
78
                $this->getHelpManager()->setShortDescription('This plugin checks the logs of the tool "LAST" an warns when users have logged in with an unexpected IP/Country/ISP.');
104
                $this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
79
                $this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.');
105
                $this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-v] [-e] [-u username] [-R regex] [--ipInfoToken token]');
80
                $this->getHelpManager()->setSyntax('$SCRIPTNAME$ [-v] [-e] [-u username] [-R regex] [--ipInfoToken token]');
106
                $this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
81
                $this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com');
107
 
82
 
108
                $this->cacheFile = $this->getIpCacheFile();
83
                $this->cacheFile = $this->get_cache_dir() . '/.last_ip_cache';
-
 
84
                if (!file_exists($this->cacheFile)) @touch($this->cacheFile);
109
                $this->cache = $this->cacheFile ? json_decode(file_get_contents($this->cacheFile),true) : array();
85
                $this->cache = $this->cacheFile ? json_decode(file_get_contents($this->cacheFile),true) : array();
110
        }
86
        }
111
 
87
 
112
        public function __destruct() {
88
        public function __destruct() {
113
                if ($this->cacheFile && $this->cacheDirty) {
89
                if ($this->cacheFile && $this->cacheDirty) {
114
                        @file_put_contents($this->cacheFile, json_encode($this->cache));
90
                        @file_put_contents($this->cacheFile, json_encode($this->cache));
115
                }
91
                }
116
        }
92
        }
117
 
93
 
118
        private function getCountryAndOrg($ip) {
94
        private function getCountryAndOrg($ip) {
119
                if (isset($this->cache[$ip])) return $this->cache[$ip];
95
                if (isset($this->cache[$ip])) return $this->cache[$ip];
120
 
96
 
121
                $url = 'https://ipinfo.io/'.urlencode($ip).'/json';
97
                $url = 'https://ipinfo.io/'.urlencode($ip).'/json';
122
                $token = $this->argIpInfoToken->getValue();
98
                $token = $this->argIpInfoToken->getValue();
123
                if ($token) $url .= '?token='.urlencode($token);
99
                if ($token) $url .= '?token='.urlencode($token);
124
 
100
 
125
                // fwrite(STDERR, "Note: Will query $url\n");
101
                // fwrite(STDERR, "Note: Will query $url\n");
126
                $cont = file_get_contents($url);
102
                $cont = file_get_contents($url);
127
                if (!$cont) return array();
103
                if (!$cont) return array();
128
                if (!($data = @json_decode($cont, true))) return array();
104
                if (!($data = @json_decode($cont, true))) return array();
129
                if (isset($data['error'])) return array();
105
                if (isset($data['error'])) return array();
130
 
106
 
131
                if (isset($data['bogon']) && ($data['bogon'])) {
107
                if (isset($data['bogon']) && ($data['bogon'])) {
132
                        // Things like 127.0.0.1 do not belong to anyone
108
                        // Things like 127.0.0.1 do not belong to anyone
133
                        $res = array();
109
                        $res = array();
134
                } else {
110
                } else {
135
                        $res = array();
111
                        $res = array();
136
                        if (isset($data['hostname'])) $res[] = $data['hostname'];
112
                        if (isset($data['hostname'])) $res[] = $data['hostname'];
137
                        if (isset($data['country'])) $res[] = $data['country'];
113
                        if (isset($data['country'])) $res[] = $data['country'];
138
                        list($as, $orgName) = explode(' ', $data['org'], 2);
114
                        list($as, $orgName) = explode(' ', $data['org'], 2);
139
                        $res[] = $as;
115
                        $res[] = $as;
140
                        $res[] = $orgName;
116
                        $res[] = $orgName;
141
                }
117
                }
142
 
118
 
143
                $this->cache[$ip] = $res;
119
                $this->cache[$ip] = $res;
144
                $this->cacheDirty = true;
120
                $this->cacheDirty = true;
145
                return $res;
121
                return $res;
146
        }
122
        }
147
 
123
 
148
        private function getLastLoginIPs($username) {
124
        private function getLastLoginIPs($username) {
149
                $cont = '';
125
                $cont = '';
150
                $files = glob($this->argWtmpFiles->getValue());
126
                $files = glob($this->argWtmpFiles->getValue());
151
                foreach ($files as $file) {
127
                foreach ($files as $file) {
152
                        if (trim($username) == '') {
128
                        if (trim($username) == '') {
153
                                $cont .= shell_exec('last -f '.escapeshellarg($file).' -F -w '); // all users
129
                                $cont .= shell_exec('last -f '.escapeshellarg($file).' -F -w '); // all users
154
                        } else {
130
                        } else {
155
                                $cont .= shell_exec('last -f '.escapeshellarg($file).' -F -w '.escapeshellarg($username));
131
                                $cont .= shell_exec('last -f '.escapeshellarg($file).' -F -w '.escapeshellarg($username));
156
                        }
132
                        }
157
                }
133
                }
158
                preg_match_all('@^(\S+)\s+(\S+)\s+(\S+)\s+(.+)$@ismU', $cont, $m, PREG_SET_ORDER);
134
                preg_match_all('@^(\S+)\s+(\S+)\s+(\S+)\s+(.+)$@ismU', $cont, $m, PREG_SET_ORDER);
159
                foreach ($m as $key => &$a) {
135
                foreach ($m as $key => &$a) {
160
                        if (($a[2] === 'system') && ($a[3] === 'boot')) {
136
                        if (($a[2] === 'system') && ($a[3] === 'boot')) {
161
                                // reboot   system boot  4.9.0-8-amd64    Fri Oct 12 02:10   still running
137
                                // reboot   system boot  4.9.0-8-amd64    Fri Oct 12 02:10   still running
162
                                unset($m[$key]);
138
                                unset($m[$key]);
163
                        } else if ($a[2] === 'begins') {
139
                        } else if ($a[2] === 'begins') {
164
                                // wtmp.1 begins Fri Oct 12 02:10:43 2018
140
                                // wtmp.1 begins Fri Oct 12 02:10:43 2018
165
                                unset($m[$key]);
141
                                unset($m[$key]);
166
                        } else {
142
                        } else {
167
                                array_shift($a);
143
                                array_shift($a);
168
                        }
144
                        }
169
                }
145
                }
170
                return $m;
146
                return $m;
171
        }
147
        }
172
 
148
 
173
        protected function cbRun() {
149
        protected function cbRun() {
174
                if (!`which which`) {
150
                if (!`which which`) {
175
                        throw new VNagException("Program 'which' is not installed on your system");
151
                        throw new VNagException("Program 'which' is not installed on your system");
176
                }
152
                }
177
 
153
 
178
                if (!`which last`) {
154
                if (!`which last`) {
179
                        throw new VNagException("Program 'last' (usually included in package smartmontools) is not installed on your system");
155
                        throw new VNagException("Program 'last' (usually included in package smartmontools) is not installed on your system");
180
                }
156
                }
181
 
157
 
182
                $username = $this->argUser->available() ? $this->argUser->getValue() : '';
158
                $username = $this->argUser->available() ? $this->argUser->getValue() : '';
183
                $regex = $this->argRegex->available() ? $this->argRegex->getValue() : null;
159
                $regex = $this->argRegex->available() ? $this->argRegex->getValue() : null;
184
 
160
 
185
                if (($username != '') && function_exists('posix_getpwnam') && !posix_getpwnam($username)) {
161
                if (($username != '') && function_exists('posix_getpwnam') && !posix_getpwnam($username)) {
186
                        $this->setStatus(VNag::STATUS_WARNING);
162
                        $this->setStatus(VNag::STATUS_WARNING);
187
                        $this->addVerboseMessage("WARNING: Currently, there is no Linux user with name '$username'.", VNag::VERBOSITY_SUMMARY);
163
                        $this->addVerboseMessage("WARNING: Currently, there is no Linux user with name '$username'.", VNag::VERBOSITY_SUMMARY);
188
                }
164
                }
189
 
165
 
190
                $count_total = 0;
166
                $count_total = 0;
191
                $count_ok = 0;
167
                $count_ok = 0;
192
                $count_warning = 0;
168
                $count_warning = 0;
193
 
169
 
194
                foreach ($this->getLastLoginIPs($username) as list($username, $pts, $ip, $times)) {
170
                foreach ($this->getLastLoginIPs($username) as list($username, $pts, $ip, $times)) {
195
                        // IP ":pts/0:S.0" means that there is a screen session
171
                        // IP ":pts/0:S.0" means that there is a screen session
196
                        if (strpos($ip,':pts/') === 0) continue;
172
                        if (strpos($ip,':pts/') === 0) continue;
197
 
173
 
198
                        $count_total++;
174
                        $count_total++;
199
 
175
 
200
                        $fields = $this->getCountryAndOrg($ip);
176
                        $fields = $this->getCountryAndOrg($ip);
201
                        $fields[] = $ip;
177
                        $fields[] = $ip;
202
 
178
 
203
                        if (is_null($regex)) {
179
                        if (is_null($regex)) {
204
                                // No regex. Just show the logins for information (status stays VNag::STATUS_UNKNOWN)
180
                                // No regex. Just show the logins for information (status stays VNag::STATUS_UNKNOWN)
205
                                $this->addVerboseMessage("INFO: ".implode(' ',$fields)." @ $username, $pts $times", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
181
                                $this->addVerboseMessage("INFO: ".implode(' ',$fields)." @ $username, $pts $times", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
206
                        } else {
182
                        } else {
207
                                $match = false;
183
                                $match = false;
208
                                foreach ($fields as $f) {
184
                                foreach ($fields as $f) {
209
                                        if (preg_match($regex, $f, $dummy)) {
185
                                        if (preg_match($regex, $f, $dummy)) {
210
                                                $match = true;
186
                                                $match = true;
211
                                                break;
187
                                                break;
212
                                        }
188
                                        }
213
                                }
189
                                }
214
 
190
 
215
                                if ($match) {
191
                                if ($match) {
216
                                        $count_ok++;
192
                                        $count_ok++;
217
                                        $this->addVerboseMessage("OK: ".implode(' ',$fields)." @ $username $pts $times", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
193
                                        $this->addVerboseMessage("OK: ".implode(' ',$fields)." @ $username $pts $times", VNag::VERBOSITY_ADDITIONAL_INFORMATION);
218
                                        $this->setStatus(VNag::STATUS_OK);
194
                                        $this->setStatus(VNag::STATUS_OK);
219
                                } else {
195
                                } else {
220
                                        $count_warning++;
196
                                        $count_warning++;
221
                                        $this->addVerboseMessage("WARNING: ".implode(' ',$fields)." @ $username $pts $times", VNag::VERBOSITY_SUMMARY);
197
                                        $this->addVerboseMessage("WARNING: ".implode(' ',$fields)." @ $username $pts $times", VNag::VERBOSITY_SUMMARY);
222
                                        $this->setStatus(VNag::STATUS_WARNING);
198
                                        $this->setStatus(VNag::STATUS_WARNING);
223
                                }
199
                                }
224
                        }
200
                        }
225
                }
201
                }
226
 
202
 
227
                if (is_null($regex)) {
203
                if (is_null($regex)) {
228
                        $this->setHeadline("Checked $count_total logins (No checks done because argument 'Regex' is missing)");
204
                        $this->setHeadline("Checked $count_total logins (No checks done because argument 'Regex' is missing)");
229
                } else {
205
                } else {
230
                        if (($count_total == 0) && ($this->argEmptyOk->count() > 0)) {
206
                        if (($count_total == 0) && ($this->argEmptyOk->count() > 0)) {
231
                                $this->setStatus(VNag::STATUS_OK);
207
                                $this->setStatus(VNag::STATUS_OK);
232
                        }
208
                        }
233
                        $this->setHeadline("Checked $count_total logins ($count_ok OK, $count_warning Warning)");
209
                        $this->setHeadline("Checked $count_total logins ($count_ok OK, $count_warning Warning)");
234
                }
210
                }
235
        }
211
        }
236
}
212
}
237
 
213