From b829de72180288707aa16e8435ecd39f1e9f9ac3 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 3 Jan 2017 09:36:33 -0500 Subject: [PATCH 1/4] Adding check that domain is resolved locally for cert management --- locales/en.json | 1 + src/yunohost/certificate.py | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/locales/en.json b/locales/en.json index 468be0c1c..25d0f6542 100644 --- a/locales/en.json +++ b/locales/en.json @@ -253,6 +253,7 @@ "certmanager_domain_http_not_working": "It seems that the domain {domain:s} cannot be accessed through HTTP. Please check your DNS and nginx configuration is okay", "certmanager_error_no_A_record": "No DNS 'A' record found for {domain:s}. You need to make your domain name point to your machine to be able to install a Let's Encrypt certificate! (If you know what you are doing, use --no-checks to disable those checks.)", "certmanager_domain_dns_ip_differs_from_public_ip": "The DNS 'A' record for domain {domain:s} is different from this server IP. If you recently modified your A record, please wait for it to propagate (some DNS propagation checkers are available online). (If you know what you are doing, use --no-checks to disable those checks.)", + "certmanager_domain_not_resolved_locally": "The domain {domain:s} cannot be resolved locally. This might happen if you recently modified your DNS record. If so, please wait a few hours for it to propagate. If the issue persists, consider adding {domain:s} to /etc/hosts. (If you know what you are doing, use --no-checks to disable those checks.)", "certmanager_cannot_read_cert": "Something wrong happened when trying to open current certificate for domain {domain:s} (file: {file:s}), reason: {reason:s}", "certmanager_cert_install_success_selfsigned": "Successfully installed a self-signed certificate for domain {domain:s}!", "certmanager_cert_install_success": "Successfully installed Let's Encrypt certificate for domain {domain:s}!", diff --git a/src/yunohost/certificate.py b/src/yunohost/certificate.py index 01852d2ec..652d6b653 100644 --- a/src/yunohost/certificate.py +++ b/src/yunohost/certificate.py @@ -785,6 +785,13 @@ def _check_domain_is_ready_for_ACME(domain): raise MoulinetteError(errno.EINVAL, m18n.n( 'certmanager_domain_http_not_working', domain=domain)) + # Check if domain is resolved locally (Might happen despite the previous + # checks because of dns propagation ?... Acme-tiny won't work in that case, + # because it explicitly requests() the domain.) + if not _domain_is_resolved_locally(domain): + raise MoulinetteError(errno.EINVAL, m18n.n( + 'certmanager_domain_not_resolved_locally', domain=domain)) + def _dns_ip_match_public_ip(public_ip, domain): try: @@ -809,6 +816,15 @@ def _domain_is_accessible_through_HTTP(ip, domain): return True +def _domain_is_resolved_locally(domain): + try: + requests.head("http://%s/" % domain) + except Exception: + return False + + return True + + def _name_self_CA(): ca_conf = os.path.join(SSL_DIR, "openssl.ca.cnf") From 86f97d6f071602d5ca9402331fa9607a8de558b6 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 4 Jan 2017 13:05:57 -0500 Subject: [PATCH 2/4] Changing the way to check domain is locally resolved --- locales/en.json | 2 +- src/yunohost/certificate.py | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/locales/en.json b/locales/en.json index 25d0f6542..387b8c2e8 100644 --- a/locales/en.json +++ b/locales/en.json @@ -253,7 +253,7 @@ "certmanager_domain_http_not_working": "It seems that the domain {domain:s} cannot be accessed through HTTP. Please check your DNS and nginx configuration is okay", "certmanager_error_no_A_record": "No DNS 'A' record found for {domain:s}. You need to make your domain name point to your machine to be able to install a Let's Encrypt certificate! (If you know what you are doing, use --no-checks to disable those checks.)", "certmanager_domain_dns_ip_differs_from_public_ip": "The DNS 'A' record for domain {domain:s} is different from this server IP. If you recently modified your A record, please wait for it to propagate (some DNS propagation checkers are available online). (If you know what you are doing, use --no-checks to disable those checks.)", - "certmanager_domain_not_resolved_locally": "The domain {domain:s} cannot be resolved locally. This might happen if you recently modified your DNS record. If so, please wait a few hours for it to propagate. If the issue persists, consider adding {domain:s} to /etc/hosts. (If you know what you are doing, use --no-checks to disable those checks.)", + "certmanager_domain_not_resolved_locally": "The domain {domain:s} cannot be resolved from inside your Yunohost server. This might happen if you recently modified your DNS record. If so, please wait a few hours for it to propagate. If the issue persists, consider adding {domain:s} to /etc/hosts. (If you know what you are doing, use --no-checks to disable those checks.)", "certmanager_cannot_read_cert": "Something wrong happened when trying to open current certificate for domain {domain:s} (file: {file:s}), reason: {reason:s}", "certmanager_cert_install_success_selfsigned": "Successfully installed a self-signed certificate for domain {domain:s}!", "certmanager_cert_install_success": "Successfully installed Let's Encrypt certificate for domain {domain:s}!", diff --git a/src/yunohost/certificate.py b/src/yunohost/certificate.py index 652d6b653..eb1e44732 100644 --- a/src/yunohost/certificate.py +++ b/src/yunohost/certificate.py @@ -31,6 +31,7 @@ import grp import smtplib import requests import subprocess +import socket import dns.resolver import glob @@ -788,7 +789,7 @@ def _check_domain_is_ready_for_ACME(domain): # Check if domain is resolved locally (Might happen despite the previous # checks because of dns propagation ?... Acme-tiny won't work in that case, # because it explicitly requests() the domain.) - if not _domain_is_resolved_locally(domain): + if not _domain_is_resolved_locally(public_ip, domain): raise MoulinetteError(errno.EINVAL, m18n.n( 'certmanager_domain_not_resolved_locally', domain=domain)) @@ -816,13 +817,13 @@ def _domain_is_accessible_through_HTTP(ip, domain): return True -def _domain_is_resolved_locally(domain): +def _domain_is_resolved_locally(public_ip, domain): try: - requests.head("http://%s/" % domain) - except Exception: + ip = socket.gethostbyname(domain) + except socket.error: return False - return True + return (ip in ["127.0.0.1", public_ip]) def _name_self_CA(): From 047026df6caa9fad6b5e4c45216a9a57a65968f6 Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Sun, 8 Jan 2017 05:28:13 +0100 Subject: [PATCH 3/4] [mod] remove () --- src/yunohost/certificate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yunohost/certificate.py b/src/yunohost/certificate.py index eb1e44732..b91bc74b6 100644 --- a/src/yunohost/certificate.py +++ b/src/yunohost/certificate.py @@ -823,7 +823,7 @@ def _domain_is_resolved_locally(public_ip, domain): except socket.error: return False - return (ip in ["127.0.0.1", public_ip]) + return ip in ["127.0.0.1", public_ip] def _name_self_CA(): From d665984789058c99ca046f707f9ecf7d20b537cd Mon Sep 17 00:00:00 2001 From: Laurent Peuch Date: Sun, 8 Jan 2017 05:31:11 +0100 Subject: [PATCH 4/4] [mod] add debugging code to avoid becoming mad when things goes wrong --- src/yunohost/certificate.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/yunohost/certificate.py b/src/yunohost/certificate.py index b91bc74b6..a53f5f669 100644 --- a/src/yunohost/certificate.py +++ b/src/yunohost/certificate.py @@ -820,9 +820,11 @@ def _domain_is_accessible_through_HTTP(ip, domain): def _domain_is_resolved_locally(public_ip, domain): try: ip = socket.gethostbyname(domain) - except socket.error: + except socket.error as e: + logger.debug("Couldn't get domain '%s' ip because: %s" % (domain, e)) return False + logger.debug("Domain '%s' ip is %s, except it to be 127.0.0.1 or %s" % (domain, public_ip)) return ip in ["127.0.0.1", public_ip]