util/prosodyctl/check.lua
changeset 11783 f4f0bdaeabd2
parent 11782 f254fd16218a
child 11784 98ae95235775
equal deleted inserted replaced
11782:f254fd16218a 11783:f4f0bdaeabd2
     4 local dependencies = require "util.dependencies";
     4 local dependencies = require "util.dependencies";
     5 local socket = require "socket";
     5 local socket = require "socket";
     6 local jid_split = require "util.jid".prepped_split;
     6 local jid_split = require "util.jid".prepped_split;
     7 local modulemanager = require "core.modulemanager";
     7 local modulemanager = require "core.modulemanager";
     8 
     8 
       
     9 local function check_api(check_type, target_host)
       
    10 	local async = require "util.async";
       
    11 	local wait, done = async.waiter();
       
    12 	local http = require "net.http"; -- .new({});
       
    13 	local urlencode = require "util.http".urlencode;
       
    14 	local json = require "util.json";
       
    15 
       
    16 	local ok = false;
       
    17 	local err = nil;
       
    18 	local decoded_body = nil;
       
    19 
       
    20 	http.request(
       
    21 		("https://observe.jabber.network/api/v1/check/%s"):format(urlencode(check_type)),
       
    22 		{
       
    23 			method="POST",
       
    24 			headers={["Accept"] = "application/json"; ["Content-Type"] = "application/json"},
       
    25 			body=json.encode({target=target_host}),
       
    26 		},
       
    27 		function (body, code)
       
    28 			if code ~= 200 then
       
    29 				err = ("API replied with non-200 code: %d"):format(code)
       
    30 			else
       
    31 				decoded_body, err = json.decode(body);
       
    32 				if decoded_body == nil then
       
    33 					err = ("Failed to parse API JSON: %s"):format(err)
       
    34 				else
       
    35 					ok = true
       
    36 				end
       
    37 			end
       
    38 			done();
       
    39 		end
       
    40 	);
       
    41 	wait();
       
    42 
       
    43 	if not ok then
       
    44 		return false, err
       
    45 	end
       
    46 
       
    47 	local success = decoded_body["success"];
       
    48 	return success == true, nil;
       
    49 end
       
    50 
       
    51 local function skip_bare_jid_hosts(host)
       
    52 	if jid_split(host) then
       
    53 		-- See issue #779
       
    54 		return false;
       
    55 	end
       
    56 	return true;
       
    57 end
       
    58 
     9 local function check(arg)
    59 local function check(arg)
    10 	if arg[1] == "--help" then
    60 	if arg[1] == "--help" then
    11 		show_usage([[check]], [[Perform basic checks on your Prosody installation]]);
    61 		show_usage([[check]], [[Perform basic checks on your Prosody installation]]);
    12 		return 1;
    62 		return 1;
    13 	end
    63 	end
    15 	local set = require "util.set";
    65 	local set = require "util.set";
    16 	local it = require "util.iterators";
    66 	local it = require "util.iterators";
    17 	local ok = true;
    67 	local ok = true;
    18 	local function disabled_hosts(host, conf) return host ~= "*" and conf.enabled ~= false; end
    68 	local function disabled_hosts(host, conf) return host ~= "*" and conf.enabled ~= false; end
    19 	local function enabled_hosts() return it.filter(disabled_hosts, pairs(configmanager.getconfig())); end
    69 	local function enabled_hosts() return it.filter(disabled_hosts, pairs(configmanager.getconfig())); end
    20 	if not (what == nil or what == "disabled" or what == "config" or what == "dns" or what == "certs") then
    70 	if not (what == nil or what == "disabled" or what == "config" or what == "dns" or what == "certs" or what == "connectivity") then
    21 		show_warning("Don't know how to check '%s'. Try one of 'config', 'dns', 'certs' or 'disabled'.", what);
    71 		show_warning("Don't know how to check '%s'. Try one of 'config', 'dns', 'certs', 'disabled' or 'connectivity'.", what);
       
    72 		show_warning("Note: The connectivity check will connect to a remote server.");
    22 		return 1;
    73 		return 1;
    23 	end
    74 	end
    24 	if not what or what == "disabled" then
    75 	if not what or what == "disabled" then
    25 		local disabled_hosts_set = set.new();
    76 		local disabled_hosts_set = set.new();
    26 		for host, host_options in it.filter("*", pairs(configmanager.getconfig())) do
    77 		for host, host_options in it.filter("*", pairs(configmanager.getconfig())) do
   604 			if what == "certs" then cert_ok = false end
   655 			if what == "certs" then cert_ok = false end
   605 		elseif not load_cert then
   656 		elseif not load_cert then
   606 			print("This version of LuaSec (" .. ssl._VERSION .. ") does not support certificate checking");
   657 			print("This version of LuaSec (" .. ssl._VERSION .. ") does not support certificate checking");
   607 			cert_ok = false
   658 			cert_ok = false
   608 		else
   659 		else
   609 			local function skip_bare_jid_hosts(host)
       
   610 				if jid_split(host) then
       
   611 					-- See issue #779
       
   612 					return false;
       
   613 				end
       
   614 				return true;
       
   615 			end
       
   616 			for host in it.filter(skip_bare_jid_hosts, enabled_hosts()) do
   660 			for host in it.filter(skip_bare_jid_hosts, enabled_hosts()) do
   617 				print("Checking certificate for "..host);
   661 				print("Checking certificate for "..host);
   618 				-- First, let's find out what certificate this host uses.
   662 				-- First, let's find out what certificate this host uses.
   619 				local host_ssl_config = configmanager.rawget(host, "ssl")
   663 				local host_ssl_config = configmanager.rawget(host, "ssl")
   620 					or configmanager.rawget(host:match("%.(.*)"), "ssl");
   664 					or configmanager.rawget(host:match("%.(.*)"), "ssl");
   675 			print("For more information about certificates please see https://prosody.im/doc/certificates");
   719 			print("For more information about certificates please see https://prosody.im/doc/certificates");
   676 			ok = false
   720 			ok = false
   677 		end
   721 		end
   678 		print("")
   722 		print("")
   679 	end
   723 	end
       
   724 	-- intentionally not doing this by default
       
   725 	if what == "connectivity" then
       
   726 		for host in it.filter(skip_bare_jid_hosts, enabled_hosts()) do
       
   727 			local modules, component_module = modulemanager.get_modules_for_host(host);
       
   728 			if component_module then
       
   729 				modules:add(component_module)
       
   730 			end
       
   731 
       
   732 			print("Checking external connectivity for "..host.." via observe.jabber.network")
       
   733 			local function check_connectivity(protocol)
       
   734 				local success, err = check_api(protocol, host);
       
   735 				if not success and err ~= nil then
       
   736 					print(("  %s: Failed to request check at API: %s"):format(protocol, err))
       
   737 				elseif success then
       
   738 					print(("  %s: Works"):format(protocol))
       
   739 				else
       
   740 					print(("  %s: Check service failed to establish (secure) connection"):format(protocol))
       
   741 					ok = false
       
   742 				end
       
   743 			end
       
   744 
       
   745 			if modules:contains("c2s") then
       
   746 				check_connectivity("xmpp-client")
       
   747 			end
       
   748 
       
   749 			if modules:contains("s2s") then
       
   750 				check_connectivity("xmpp-server")
       
   751 			end
       
   752 
       
   753 			print()
       
   754 		end
       
   755 		print("Note: The connectivity check only checks the reachability of the domain.")
       
   756 		print("Note: It does not ensure that the check actually reaches this specific prosody instance.")
       
   757 	end
   680 	if not ok then
   758 	if not ok then
   681 		print("Problems found, see above.");
   759 		print("Problems found, see above.");
   682 	else
   760 	else
   683 		print("All checks passed, congratulations!");
   761 		print("All checks passed, congratulations!");
   684 	end
   762 	end