From f1c9248f6b9ec0bc80c19e8eaa437ea066d3a8f8 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 17 May 2013 13:35:12 +0100 Subject: prosodyctl: Add 'prosodyctl check dns' to make an attempt at verifying the server's DNS records --- prosodyctl | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 1 deletion(-) (limited to 'prosodyctl') diff --git a/prosodyctl b/prosodyctl index 262be676..d3ba8932 100755 --- a/prosodyctl +++ b/prosodyctl @@ -818,7 +818,148 @@ function commands.check(arg) print(" You need to move the following option"..(n>1 and "s" or "")..": "..table.concat(it.to_array(misplaced_options), ", ")); end end - print("Done."); + print("Done.\n"); + end + if not what or what == "dns" then + local dns = require "net.dns"; + local c2s_ports = set.new(config.get("*", "c2s_ports") or {5222}); + local s2s_ports = set.new(config.get("*", "s2s_ports") or {5269}); + + local c2s_srv_required, s2s_srv_required; + if not c2s_ports:contains(5222) then + c2s_srv_required = true; + end + if not s2s_ports:contains(5269) then + s2s_srv_required = true; + end + + local problem_hosts = set.new(); + + local external_addresses = set.new(); + + local fqdn = socket.dns.tohostname(socket.dns.gethostname()); + if fqdn then + local res = dns.lookup(fqdn, "A"); + if res then + for _, record in ipairs(res) do + external_addresses:add(record.a); + end + end + local res = dns.lookup(fqdn, "AAAA"); + if res then + for _, record in ipairs(res) do + external_addresses:add(record.aaaa); + end + end + end + + if external_addresses:empty() then + print(""); + print(" Failed to determine the external addresses of this server. Checks may be inaccurate."); + c2s_srv_required, s2s_srv_required = true, true; + end + + local v6_supported = not not socket.tcp6; + + for host, host_options in it.filter("*", pairs(config.getconfig())) do + local all_targets_ok, some_targets_ok = true, false; + + local is_component = not not host_options.component_module; + print("Checking DNS for "..(is_component and "component" or "host").." "..host.."..."); + local target_hosts = set.new(); + if not is_component then + local res = dns.lookup("_xmpp-client._tcp."..host..".", "SRV"); + if res then + for _, record in ipairs(res) do + target_hosts:add(record.srv.target); + if not c2s_ports:contains(record.srv.port) then + print(" SRV target "..record.srv.target.." contains unknown client port: "..record.srv.port); + end + end + else + if c2s_srv_required then + print(" No _xmpp-client SRV record found for "..host..", but it looks like you need one."); + else + target_hosts:add(host); + end + end + end + local res = dns.lookup("_xmpp-server._tcp."..host..".", "SRV"); + if res then + for _, record in ipairs(res) do + target_hosts:add(record.srv.target); + if not s2s_ports:contains(record.srv.port) then + print(" SRV target "..record.srv.target.." contains unknown server port: "..record.srv.port); + end + end + else + if s2s_srv_required then + print(" No _xmpp-server SRV record found for "..host..", but it looks like you need one."); + else + target_hosts:add(host); + end + end + if target_hosts:empty() then + target_hosts:add(host); + end + + if target_hosts:contains("localhost") then + print(" Target 'localhost' cannot be accessed from other servers"); + target_hosts:remove("localhost"); + end + + for host in target_hosts do + local host_ok_v4, host_ok_v6; + local res = dns.lookup(host, "A"); + if res then + for _, record in ipairs(res) do + if external_addresses:contains(record.a) then + some_targets_ok = true; + host_ok_v4 = true; + else + print(" "..host.." A record points to unknown address "..record.a); + all_targets_ok = false; + end + end + end + local res = dns.lookup(host, "AAAA"); + if res then + for _, record in ipairs(res) do + if external_addresses:contains(record.aaaa) then + some_targets_ok = true; + host_ok_v6 = true; + else + print(" "..host.." AAAA record points to unknown address "..record.aaaa); + all_targets_ok = false; + end + end + end + + if not host_ok_v4 then + print(" Host "..host.." does not seem to resolve to this server for IPv4"); + end + if not host_ok_v6 and v6_supported then + print(" Host "..host.." does not seem to resolve to this server for IPv6"); + elseif host_ok_v6 and not v6_supported then + print(" Host "..host.." has AAAA records, but your version of LuaSocket does not support IPv6."); + print(" Please see http://prosody.im/doc/ipv6 for more information."); + end + end + if not all_targets_ok then + print(" "..(some_targets_ok and "Only some" or "No").." targets for "..host.." appear to resolve to this server."); + if is_component then + print(" DNS records are necessary if you want users on other servers to access this component."); + end + print(""); + problem_hosts:add(host); + end + end + if not problem_hosts:empty() then + print(""); + print("For more information about DNS configuration please see http://prosody.im/doc/dns"); + print(""); + ok = false; + end end if not ok then print("Problems found, see above."); -- cgit v1.2.3