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 |