diff --git a/certbot/certbot/_internal/plugins/standalone.py b/certbot/certbot/_internal/plugins/standalone.py index 5fb29671f..db03744e8 100644 --- a/certbot/certbot/_internal/plugins/standalone.py +++ b/certbot/certbot/_internal/plugins/standalone.py @@ -5,6 +5,7 @@ import logging import socket from typing import DefaultDict from typing import Dict +from typing import List from typing import Set from typing import Tuple from typing import TYPE_CHECKING @@ -184,6 +185,14 @@ class Authenticator(common.Plugin): if not self.served[servers]: self.servers.stop(port) + def auth_hint(self, failed_achalls: List[achallenges.AnnotatedChallenge]) -> str: + port, addr = self.config.http01_port, self.config.http01_address + neat_addr = f"{addr}:{port}" if addr else f"port {port}" + return ("The Certificate Authority failed to download the challenge files from " + f"the temporary standalone webserver started by Certbot on {neat_addr}. " + "Ensure that the listed domains point to this machine and that it can " + "accept inbound connections from the internet.") + def _handle_perform_error(error): if error.socket_error.errno == errno.EACCES: diff --git a/certbot/tests/plugins/standalone_test.py b/certbot/tests/plugins/standalone_test.py index 6f2ae91ba..7f55b892d 100644 --- a/certbot/tests/plugins/standalone_test.py +++ b/certbot/tests/plugins/standalone_test.py @@ -177,6 +177,13 @@ class AuthenticatorTest(unittest.TestCase): "server1": set(), "server2": set()}) self.auth.servers.stop.assert_called_with(2) + def test_auth_hint(self): + self.config.http01_port = "80" + self.config.http01_address = None + self.assertIn("on port 80", self.auth.auth_hint([])) + self.config.http01_address = "127.0.0.1" + self.assertIn("on 127.0.0.1:80", self.auth.auth_hint([])) + if __name__ == "__main__": unittest.main() # pragma: no cover