[heartbeat] update the heartbeat to use JSON/HTTPS
This commit is contained in:
parent
2d42dce5f6
commit
f94e74ddc7
|
@ -0,0 +1,141 @@
|
|||
#!/usr/bin/env lua
|
||||
|
||||
--[[
|
||||
|
||||
heartbeat.lua - send a heartbeat to the flukso server
|
||||
|
||||
Copyright (C) 2008-2009 jokamajo.org
|
||||
2011 Bart Van Der Meerssche <bart.vandermeerssche@flukso.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
]]--
|
||||
|
||||
if not arg[1] then
|
||||
print ('Please pass the reset argument as a boolean to the script.')
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
local dbg = require 'dbg'
|
||||
local nixio = require 'nixio'
|
||||
nixio.fs = require 'nixio.fs'
|
||||
local uci = require 'luci.model.uci'.cursor()
|
||||
local luci = require 'luci'
|
||||
luci.sys = require 'luci.sys'
|
||||
luci.json = require 'luci.json'
|
||||
local httpclient = require 'luci.httpclient'
|
||||
|
||||
-- WAN settings
|
||||
local WAN_BASE_URL = 'https://api.flukso.net/device/'
|
||||
local WAN_KEY = '0123456789abcdef0123456789abcdef'
|
||||
uci:foreach('system', 'system', function(x) WAN_KEY = x.key end) -- quirky but it works
|
||||
|
||||
local DEVICE = '0123456789abcdef0123456789abcdef'
|
||||
uci:foreach('system', 'system', function(x) DEVICE = x.device end)
|
||||
|
||||
local UPGRADE_URL = 'http://www.flukso.net/files/upgrade/'
|
||||
|
||||
-- https header helpers
|
||||
local FLUKSO_VERSION = '000'
|
||||
uci:foreach('system', 'system', function(x) FLUKSO_VERSION = x.version end)
|
||||
|
||||
local USER_AGENT = 'Fluksometer v' .. FLUKSO_VERSION
|
||||
local CACERT = '/etc/ssl/certs/flukso.ca.crt'
|
||||
|
||||
-- collect relevant monitoring points
|
||||
function collect_mp()
|
||||
local monitor = {}
|
||||
|
||||
monitor.reset = tonumber(arg[1])
|
||||
monitor.version = tonumber(FLUKSO_VERSION)
|
||||
monitor.uptime = math.floor(luci.sys.uptime())
|
||||
system, model, monitor.memtotal, monitor.memcached, monitor.membuffers, monitor.memfree = luci.sys.sysinfo()
|
||||
|
||||
return monitor
|
||||
end
|
||||
|
||||
-- open the connection to the syslog deamon, specifying our identity
|
||||
nixio.openlog('heartbeat', 'pid')
|
||||
|
||||
local monitor = collect_mp()
|
||||
local monitor_json = luci.json.encode(monitor)
|
||||
|
||||
|
||||
-- phone home
|
||||
local headers = {}
|
||||
headers['Content-Type'] = 'application/json'
|
||||
headers['X-Version'] = '1.0'
|
||||
headers['User-Agent'] = USER_AGENT
|
||||
headers['Connection'] = 'close'
|
||||
|
||||
local options = {}
|
||||
options.sndtimeo = 5
|
||||
options.rcvtimeo = 5
|
||||
-- We don't enable peer cert verification so we can still update/upgrade
|
||||
-- the Fluksometer via the heartbeat call even when the cacert has expired.
|
||||
-- Disabling validation does mean that the server has to include an hmac
|
||||
-- digest in the reply that the Fluksometer needs to verify, this to prevent
|
||||
-- man-in-the-middle attacks.
|
||||
options.tls_context_set_verify = 'none'
|
||||
-- options.cacert = CACERT
|
||||
options.method = 'POST'
|
||||
options.headers = headers
|
||||
options.body = luci.json.encode(monitor)
|
||||
|
||||
local hash = nixio.crypto.hmac('sha1', WAN_KEY)
|
||||
hash:update(options.body)
|
||||
options.headers['X-Digest'] = hash:final()
|
||||
|
||||
local http_persist = httpclient.create_persistent()
|
||||
local url = WAN_BASE_URL .. DEVICE
|
||||
local response_json, code, call_info = http_persist(url, options)
|
||||
|
||||
if code == 200 then
|
||||
nixio.syslog('info', string.format('%s %s: %s', options.method, url, code))
|
||||
else
|
||||
nixio.syslog('err', string.format('%s %s: %s', options.method, url, code))
|
||||
|
||||
-- if available, send additional error info to the syslog
|
||||
if type(call_info) == 'string' then
|
||||
nixio.syslog('err', call_info)
|
||||
elseif type(call_info) == 'table' then
|
||||
local auth_error = call_info.headers['WWW-Authenticate']
|
||||
|
||||
if auth_error then
|
||||
nixio.syslog('err', string.format('WWW-Authenticate: %s', auth_error))
|
||||
end
|
||||
end
|
||||
|
||||
os.exit(2)
|
||||
end
|
||||
|
||||
-- verify the reply's digest
|
||||
hash = nixio.crypto.hmac('sha1', WAN_KEY)
|
||||
hash:update(response)
|
||||
if call_info.headers['X-Digest'] ~= hash:final() then
|
||||
nixio.syslog('err', 'Incorrect digest in the heartbeat reply. Discard response.')
|
||||
os.exit(3)
|
||||
end
|
||||
|
||||
-- check whether we have to reset or upgrade
|
||||
local response = luci.json.decode(response_json)
|
||||
|
||||
if response.upgrade == monitor.version then
|
||||
os.execute('reboot')
|
||||
elseif response.upgrade > monitor.version then
|
||||
os.execute('wget -P /tmp ' .. UPGRADE_URL .. 'upgrade.' .. response.upgrade)
|
||||
os.execute('chmod a+x /tmp/upgrade.' .. response.upgrade)
|
||||
os.execute('/tmp/upgrade.' .. response.upgrade)
|
||||
os.execute('rm /tmp/upgrade.' .. response.upgrade)
|
||||
end
|
Loading…
Reference in New Issue