diff --git a/data/hooks/diagnosis/14-ports.py b/data/hooks/diagnosis/14-ports.py index b953f35a9..a845174b6 100644 --- a/data/hooks/diagnosis/14-ports.py +++ b/data/hooks/diagnosis/14-ports.py @@ -5,7 +5,7 @@ import requests from yunohost.diagnosis import Diagnoser from yunohost.utils.error import YunohostError - +from yunohost.service import _get_services class PortsDiagnoser(Diagnoser): @@ -15,16 +15,18 @@ class PortsDiagnoser(Diagnoser): def run(self): - # FIXME / TODO : in the future, maybe we want to report different - # things per port depending on how important they are - # (e.g. XMPP sounds to me much less important than other ports) - # Ideally, a port could be related to a service... - # FIXME / TODO : for now this list of port is hardcoded, might want - # to fetch this from the firewall.yml in /etc/yunohost/ - ports = [22, 25, 53, 80, 443, 587, 993, 5222, 5269] + # This dict is something like : + # { 80: "nginx", + # 25: "postfix", + # 443: "nginx" + # ... } + ports = {} + for service, infos in _get_services().items(): + for port in infos.get("needs_exposed_ports", []): + ports[port] = service try: - r = requests.post('https://ynhdiagnoser.netlib.re/check-ports', json={'ports': ports}, timeout=30).json() + r = requests.post('https://ynhdiagnoser.netlib.re/check-ports', json={'ports': ports.keys()}, timeout=30).json() if "status" not in r.keys(): raise Exception("Bad syntax for response ? Raw json: %s" % str(r)) elif r["status"] == "error": @@ -37,15 +39,17 @@ class PortsDiagnoser(Diagnoser): except Exception as e: raise YunohostError("diagnosis_ports_could_not_diagnose", error=e) - for port in ports: + for port, service in ports.items(): if r["ports"].get(str(port), None) is not True: - yield dict(meta={"port": port}, + yield dict(meta={"port": port, "needed_by": service}, status="ERROR", - summary=("diagnosis_ports_unreachable", {"port": port})) + summary=("diagnosis_ports_unreachable", {"port": port}), + details=[("diagnosis_ports_needed_by", (service,)), ("diagnosis_ports_forwarding_tip", ())]) else: - yield dict(meta={}, + yield dict(meta={"port": port, "needed_by": service}, status="SUCCESS", - summary=("diagnosis_ports_ok", {"port": port})) + summary=("diagnosis_ports_ok", {"port": port}), + details=[("diagnosis_ports_needed_by", (service))]) def main(args, env, loggers): diff --git a/data/templates/yunohost/services.yml b/data/templates/yunohost/services.yml index fd9d06eac..986beb271 100644 --- a/data/templates/yunohost/services.yml +++ b/data/templates/yunohost/services.yml @@ -1,6 +1,7 @@ nginx: log: /var/log/nginx test-conf: nginx -t + needs_exposed_ports: [80, 443] avahi-daemon: log: /var/log/daemon.log dnsmasq: @@ -9,9 +10,11 @@ fail2ban: log: /var/log/fail2ban.log dovecot: log: [/var/log/mail.log,/var/log/mail.err] + needs_exposed_ports: [993] postfix: log: [/var/log/mail.log,/var/log/mail.err] test-status: systemctl show postfix@- | grep -q "^SubState=running" + needs_exposed_ports: [25, 587] rspamd: log: /var/log/rspamd/rspamd.log redis-server: @@ -22,8 +25,10 @@ mysql: ssh: log: /var/log/auth.log test-conf: sshd -t + needs_exposed_ports: [22] metronome: log: [/var/log/metronome/metronome.log,/var/log/metronome/metronome.err] + needs_exposed_ports: [5222, 5269] slapd: log: /var/log/syslog php7.0-fpm: diff --git a/locales/en.json b/locales/en.json index f3a6c662e..581f38bef 100644 --- a/locales/en.json +++ b/locales/en.json @@ -216,6 +216,8 @@ "diagnosis_ports_could_not_diagnose": "Could not diagnose if ports are reachable from outside. Error: {error}", "diagnosis_ports_unreachable": "Port {port} is not reachable from outside.", "diagnosis_ports_ok": "Port {port} is reachable from outside.", + "diagnosis_ports_needed_by": "Exposing this port is needed for service {0}", + "diagnosis_ports_forwarding_tip": "To fix this issue, most probably you need to configure port forwarding on your internet router as described in https://yunohost.org/port_forwarding", "diagnosis_http_could_not_diagnose": "Could not diagnose if domain is reachable from outside. Error: {error}", "diagnosis_http_ok": "Domain {domain} is reachable from outside.", "diagnosis_http_unreachable": "Domain {domain} is unreachable through HTTP from outside.",