root/src/modules-lua/noit/module/tcp.lua

Revision a02eba18f24e8197b6999a5870d5a8aeaeeff0e0, 7.4 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 5 years ago)

reworked slightly and added ssl context metrics to Leon's submitted check. closes #192

  • Property mode set to 100644
Line 
1 -- Copyright (c) 2009, OmniTI Computer Consulting, Inc.
2 -- All rights reserved.
3 --
4 -- Redistribution and use in source and binary forms, with or without
5 -- modification, are permitted provided that the following conditions are
6 -- met:
7 --
8 --     * Redistributions of source code must retain the above copyright
9 --       notice, this list of conditions and the following disclaimer.
10 --     * Redistributions in binary form must reproduce the above
11 --       copyright notice, this list of conditions and the following
12 --       disclaimer in the documentation and/or other materials provided
13 --       with the distribution.
14 --     * Neither the name OmniTI Computer Consulting, Inc. nor the names
15 --       of its contributors may be used to endorse or promote products
16 --       derived from this software without specific prior written
17 --       permission.
18 --
19 -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 -- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 -- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 -- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 -- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 -- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 -- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 -- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 -- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 -- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 module(..., package.seeall)
32
33 function onload(image)
34   image.xml_description([=[
35 <module>
36   <name>tcp</name>
37   <description><para>TCP metrics check.</para></description>
38   <loader>lua</loader>
39   <object>noit.module.tcp</object>
40   <moduleconfig />
41   <checkconfig>
42     <parameter name="port" required="required"
43                allowed="\d+">Specifies the port on which the management interface can be reached.</parameter>
44     <parameter name="banner_match" required="optional"
45               allowed=".+">This regular expression is matched against the response banner.  If a match is not found, the check will be marked as bad.</parameter>
46     <parameter name="use_ssl" required="optional" allowed="^(?:true|false|on|off)$" default="false">Upgrade TCP connection to use SSL.</parameter>
47     <parameter name="ca_chain"
48                required="optional"
49                allowed=".+">A path to a file containing all the certificate authorities that should be loaded to validat
50 e the remote certificate (for SSL checks).</parameter>
51     <parameter name="certificate_file"
52                required="optional"
53                allowed=".+">A path to a file containing the client certificate that will be presented to the remote serv
54 er (for SSL checks).</parameter>
55     <parameter name="key_file"
56                required="optional"
57                allowed=".+">A path to a file containing key to be used in conjunction with the cilent certificate (for S
58 SL checks).</parameter>
59     <parameter name="ciphers"
60                required="optional"
61                allowed=".+">A list of ciphers to be used in the SSL protocol (for SSL checks).</parameter>
62   </checkconfig>
63   <examples>
64     <example>
65       <title>Checking TCP connection.</title>
66       <para>This example checks IMAP connection with and without SSL.</para>
67       <programlisting><![CDATA[
68       <noit>
69         <modules>
70           <loader image="lua" name="lua">
71             <config><directory>/opt/reconnoiter/libexec/modules-lua/?.lua</directory></config>
72           </loader>
73           <module loader="lua" name="tcp" object="noit.module.tcp" />
74         </modules>
75         <checks>
76           <imaps target="10.0.7.2" module="tcp" period="10000" timeout="5000">
77             <check uuid="79ba881e-ad2e-11de-9fb0-a322e3288ca7" name="imap">
78               <config>
79                 <port>143</port>
80                 <banner_match>^\* OK</banner_match>
81               </config>
82             </check>
83             <check uuid="a18659c2-add8-11de-bd01-7ff0e1a67246" name="imaps">
84               <config>
85                 <port>993</port>
86                 <banner_match>^\* OK</banner_match>
87                 <use_ssl>true</use_ssl>
88               </config>
89             </check>
90           </imaps>
91         </checks>
92       </noit>
93     ]]></programlisting>
94     </example>
95   </examples>
96
97 </module>
98 ]=]);
99   return 0
100 end
101
102 function init(module)
103   return 0
104 end
105
106 function config(module, options)
107   return 0
108 end
109
110 function elapsed(check, name, starttime, endtime)
111     local elapsedtime = endtime - starttime
112     local seconds = string.format('%.3f', noit.timeval.seconds(elapsedtime))
113     check.metric_uint32(name, math.floor(seconds * 1000 + 0.5))
114     return seconds
115 end
116
117 function initiate(module, check)
118   local starttime = noit.timeval.now()
119   local max_len = 80
120   check.bad()
121   check.unavailable()
122   check.status("unknown error")
123   local good = false
124   local status = ""
125   local use_ssl = false
126
127   if check.config.port == nil then
128     check.status("port is not specified")
129     return
130   end
131
132   -- SSL
133   if check.config.use_ssl == "true" or check.config.use_ssl == "on" then
134     use_ssl = true
135   end
136
137   local e = noit.socket()
138   local rv, err = e:connect(check.target, check.config.port)
139
140   if rv ~= 0 then
141     check.status(err or "connect error")
142     return
143   end
144
145   if use_ssl == true then
146     rv, err = e:ssl_upgrade_socket(check.config.certificate_file,
147                                         check.config.key_file,
148                                         check.config.ca_chain,
149                                         check.config.ciphers)
150   end
151
152   local connecttime = noit.timeval.now()
153   elapsed(check, "tt_connect", starttime, connecttime)
154   if rv ~= 0 then
155     check.status(err or "connection failed")
156     return
157   end
158
159   status = "connected"
160   check.available()
161   good = true
162
163   -- ssl metrics
164   local ssl_ctx = e:ssl_ctx()
165   if ssl_ctx ~= nil then
166     if ssl_ctx.error ~= nil then status = status .. ',sslerror' end
167     check.metric_string("cert_error", ssl_ctx.error)
168     check.metric_string("cert_issuer", ssl_ctx.issuer)
169     check.metric_string("cert_subject", ssl_ctx.subject)
170     check.metric_uint32("cert_start", ssl_ctx.start_time)
171     check.metric_uint32("cert_end", ssl_ctx.end_time)
172     if noit.timeval.seconds(starttime) > ssl_ctx.end_time then
173       good = false
174       status = status .. ',ssl=expired'
175     end
176   end
177
178
179   -- match banner
180   if check.config.banner_match ~= nil then
181     str = e:read("\n")
182     local firstbytetime = noit.timeval.now()
183     elapsed(check, "tt_firstbyte", starttime, firstbytetime)
184
185     local bannerre = noit.pcre(check.config.banner_match)
186     if bannerre ~= nil then
187       local rv, m, m1 = bannerre(str)
188       if rv then
189         m = m1 or m or str
190         if string.len(m) > max_len then
191           m = string.sub(m,1,max_len)
192         end
193         status = status .. ',banner_match=matched'
194         check.metric_string('banner_match',m)
195       else
196         good = false
197         status = status .. ',banner_match=failed'
198       end
199     end
200     if string.len(str) > max_len then
201       str = string.sub(str,1,max_len)
202     end
203     check.metric_string('banner',str)
204   end
205
206   -- turnaround time
207   local endtime = noit.timeval.now()
208   local seconds = elapsed(check, "duration", starttime, endtime)
209   status = status .. ',rt=' .. seconds .. 's'
210   if good then check.good() else check.bad() end
211   check.status(status)
212
213 end
214
Note: See TracBrowser for help on using the browser.