import os
import time
from datetime
import timedelta
import pytest
from pyhttpd.certs
import CertificateSpec
from pyhttpd.env
import HttpdTestEnv
from .md_cert_util
import MDCertUtil
from .md_env
import MDTestEnv
from .md_conf
import MDConf
@pytest.mark.skipif(condition=
not MDTestEnv.has_acme_server(),
reason=
"no ACME test server configured")
class TestAutov2:
@pytest.fixture(autouse=
True, scope=
'class')
def _class_scope(self, env, acme):
env.APACHE_CONF_SRC =
"data/test_auto"
acme.start(config=
'default')
env.check_acme()
env.clear_store()
MDConf(env).install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
@pytest.fixture(autouse=
True, scope=
'function')
def _method_scope(self, env, request):
env.clear_store()
self.test_domain = env.get_request_domain(request)
def _write_res_file(self, doc_root, name, content):
if not os.path.exists(doc_root):
os.makedirs(doc_root)
open(os.path.join(doc_root, name),
"w").write(content)
# create a MD not used in any virtual host, auto drive should NOT pick it up
def test_md_702_001(self, env):
domain = self.test_domain
# generate config with one MD
domains = [domain,
"www." + domain]
conf = MDConf(env, admin=
"admin@" + domain)
conf.add_drive_mode(
"auto")
conf.add_md(domains)
conf.install()
#
# restart, check that MD is synched to store
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains)
stat = env.get_md_status(domain)
assert stat[
"watched"] == 0
#
# add vhost for MD, restart should drive it
conf.add_vhost(domains)
conf.install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
assert env.await_completion([domain])
env.check_md_complete(domain)
stat = env.get_md_status(domain)
assert stat[
"watched"] == 1
cert = env.get_cert(domain)
assert domain
in cert.get_san_list()
#
# challenges should have been removed
# file system needs to have correct permissions
env.check_dir_empty(env.store_challenges())
env.check_file_permissions(domain)
#
env.httpd_error_log.ignore_recent(
lognos = [
"AH10045" # No VirtualHost matches Managed Domain test-md-702-001-1688648129.org
]
)
# test case: same as test_702_001, but with two parallel managed domains
def test_md_702_002(self, env):
domain = self.test_domain
domain_a =
"a-" + domain
domain_b =
"b-" + domain
#
# generate config with two MDs
domains_a = [domain_a,
"www." + domain_a]
domains_b = [domain_b,
"www." + domain_b]
conf = MDConf(env)
conf.add_drive_mode(
"auto")
conf.add_md(domains_a)
conf.add_md(domains_b)
conf.add_vhost(domains_a)
conf.add_vhost(domains_b)
conf.install()
#
# restart, check that md is in store
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains_a)
env.check_md(domains_b)
#
# await drive completion, do not restart
assert env.await_completion([domain_a, domain_b], restart=
False)
# staged certificates are now visible on the status resources
status = env.get_md_status(domain_a)
assert 'renewal' in status
assert 'cert' in status[
'renewal']
assert 'rsa' in status[
'renewal'][
'cert']
assert 'sha256-fingerprint' in status[
'renewal'][
'cert'][
'rsa']
# check the non-staged status
assert status[
'state'] == 1
assert status[
'state-descr'] ==
"certificate(rsa) is missing"
# restart and activate
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
# check: SSL is running OK
cert_a = env.get_cert(domain_a)
assert domains_a == cert_a.get_san_list()
cert_b = env.get_cert(domain_b)
assert domains_b == cert_b.get_san_list()
# check that we created only one account
md_a = env.get_md_status(domain_a)
md_b = env.get_md_status(domain_b)
assert md_a[
'ca'] == md_b[
'ca']
# test case: one MD, that covers two vhosts
def test_md_702_003(self, env):
domain = self.test_domain
name_a =
"test-a." + domain
name_b =
"test-b." + domain
domains = [domain, name_a, name_b]
#
# generate 1 MD and 2 vhosts
conf = MDConf(env, admin=
"admin@" + domain)
conf.add_md(domains)
conf.add_vhost(name_a, doc_root=
"htdocs/a")
conf.add_vhost(name_b, doc_root=
"htdocs/b")
conf.install()
#
# create docRoot folder
self._write_res_file(os.path.join(env.server_docs_dir,
"a"),
"name.txt", name_a)
self._write_res_file(os.path.join(env.server_docs_dir,
"b"),
"name.txt", name_b)
#
# restart (-> drive), check that MD was synched and completes
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains)
assert env.await_completion([domain])
md = env.check_md_complete(domain)
assert md[
'ca'][
'url'], f
"URL of CA used not set in md: {md}"
#
# check: SSL is running OK
cert_a = env.get_cert(name_a)
assert name_a
in cert_a.get_san_list()
cert_b = env.get_cert(name_b)
assert name_b
in cert_b.get_san_list()
assert cert_a.same_serial_as(cert_b)
#
assert env.get_content(name_a,
"/name.txt") == name_a
assert env.get_content(name_b,
"/name.txt") == name_b
# test case: drive with using single challenge type explicitly
@pytest.mark.parametrize(
"challenge_type", [
"tls-alpn-01",
"http-01",
])
def test_md_702_004(self, env, challenge_type):
domain = self.test_domain
domains = [domain,
"www." + domain]
#
# generate 1 MD and 1 vhost
conf = MDConf(env, admin=
"admin@" + domain)
conf.add(
"Protocols http/1.1 acme-tls/1")
conf.add_drive_mode(
"auto")
conf.add(f
"MDCAChallenges {challenge_type}")
conf.add_md(domains)
conf.add_vhost(domains)
conf.install()
#
# restart (-> drive), check that MD was synched and completes
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains)
assert env.await_completion([domain])
env.check_md_complete(domain)
#
# check SSL running OK
cert = env.get_cert(domain)
assert domain
in cert.get_san_list()
# test case: drive_mode manual, check that server starts, but requests to domain are 503'd
def test_md_702_005(self, env):
domain = self.test_domain
name_a =
"test-a." + domain
domains = [domain, name_a]
#
# generate 1 MD and 1 vhost
conf = MDConf(env, admin=
"admin@" + domain)
conf.add_drive_mode(
"manual")
conf.add_md(domains)
conf.add_vhost(name_a, doc_root=
"htdocs/a")
conf.install()
#
# create docRoot folder
self._write_res_file(os.path.join(env.server_docs_dir,
"a"),
"name.txt", name_a)
#
# restart, check that md is in store
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains)
#
# check: that request to domains give 503 Service Unavailable
cert1 = env.get_cert(name_a)
assert name_a
in cert1.get_san_list()
assert env.get_http_status(name_a,
"/name.txt") == 503
#
# check temporary cert from server
cert2 = MDCertUtil(env.path_fallback_cert(domain))
assert cert1.same_serial_as(cert2), \
"Unexpected temporary certificate on vhost %s. Expected cn: %s , "\
"but found cn: %s" % (name_a, cert2.get_cn(), cert1.get_cn())
# test case: drive MD with only invalid challenges, domains should stay 503'd
def test_md_702_006(self, env):
domain = self.test_domain
name_a =
"test-a." + domain
domains = [domain, name_a]
#
# generate 1 MD, 1 vhost
conf = MDConf(env, admin=
"admin@" + domain)
conf.add(
"MDCAChallenges invalid-01 invalid-02")
conf.add_md(domains)
conf.add_vhost(name_a, doc_root=
"htdocs/a")
conf.install()
#
# create docRoot folder
self._write_res_file(os.path.join(env.server_docs_dir,
"a"),
"name.txt", name_a)
#
# restart, check that md is in store
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains)
# await drive completion
md = env.await_error(domain)
assert md
assert md[
'renewal'][
'errors'] > 0
assert md[
'renewal'][
'last'][
'problem'] ==
'challenge-mismatch'
assert 'account' not in md[
'ca']
#
# check: that request to domains give 503 Service Unavailable
cert = env.get_cert(name_a)
assert name_a
in cert.get_san_list()
assert env.get_http_status(name_a,
"/name.txt") == 503
#
env.httpd_error_log.ignore_recent(
lognos = [
"AH10056" # None of offered challenge types
],
matches = [
r
'.*problem\[challenge-mismatch\].*'
]
)
# Specify a non-working http proxy
def test_md_702_008(self, env):
domain = self.test_domain
domains = [domain]
#
conf = MDConf(env, admin=
"admin@" + domain)
conf.add_drive_mode(
"always")
conf.add(
"MDHttpProxy http://localhost:1")
conf.add_md(domains)
conf.install()
#
# - restart (-> drive)
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
# await drive completion
md = env.await_error(domain)
assert md
assert md[
'renewal'][
'errors'] > 0
assert md[
'renewal'][
'last'][
'status-description'] ==
'Connection refused'
assert 'account' not in md[
'ca']
#
env.httpd_error_log.ignore_recent(
lognos = [
"AH10056" # Unsuccessful in contacting ACME server
],
matches = [
r
'.*Unsuccessful in contacting ACME server at .*'
]
)
# Specify a valid http proxy
def test_md_702_008a(self, env):
domain = self.test_domain
domains = [domain]
#
conf = MDConf(env, admin=f
"admin@{domain}", proxy=
True)
conf.add_drive_mode(
"always")
conf.add(f
"MDHttpProxy http://localhost:{env.proxy_port}")
conf.add_md(domains)
conf.install()
#
# - restart (-> drive), check that md is in store
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
assert env.await_completion([domain])
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md_complete(domain)
# Force cert renewal due to critical remaining valid duration
# Assert that new cert activation is delayed
def test_md_702_009(self, env):
domain = self.test_domain
domains = [domain]
#
# prepare md
conf = MDConf(env, admin=
"admin@" + domain)
conf.add_drive_mode(
"auto")
conf.add_renew_window(
"10d")
conf.add_md(domains)
conf.add_vhost(domain)
conf.install()
#
# restart (-> drive), check that md+cert is in store, TLS is up
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
assert env.await_completion([domain], restart=
False)
# Overwrite stages cert with one which has little remaining lifetime
creds = env.create_self_signed_cert(CertificateSpec(domains=[domain]),
valid_from=timedelta(days=-120),
valid_to=timedelta(days=2),
serial=7029)
assert creds.certificate.serial_number == 7029
creds.save_cert_pem(env.store_staged_file(domain,
'pubcert.pem'))
creds.save_pkey_pem(env.store_staged_file(domain,
'privkey.pem'))
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
stat = env.get_certificate_status(domain)
assert creds.certificate.serial_number == int(stat[
'rsa'][
'serial'], 16)
# cert should renew and be different afterwards
assert env.await_completion([domain], must_renew=
True)
stat = env.get_certificate_status(domain)
assert creds.certificate.serial_number != int(stat[
'rsa'][
'serial'], 16)
# test case: drive with an unsupported challenge due to port availability
def test_md_702_010(self, env):
domain = self.test_domain
domains = [domain,
"www." + domain]
#
# generate 1 MD and 1 vhost, map port 80 to where the server does not listen
conf = MDConf(env, admin=
"admin@" + domain)
conf.add_drive_mode(
"auto")
conf.add(
"MDPortMap 80:99")
conf.add_md(domains)
conf.add_vhost(domains)
conf.install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
md = env.await_error(domain)
assert md[
"renewal"][
"errors"] > 0
#
# now the same with a 80 mapped to a supported port
conf = MDConf(env, admin=
"admin@" + domain)
conf.add_drive_mode(
"auto")
conf.add(
"MDCAChallenges http-01")
conf.add(
"MDPortMap 80:%s" % env.http_port)
conf.add_md(domains)
conf.add_vhost(domains)
conf.install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains)
assert env.await_completion([domain])
#
env.httpd_error_log.ignore_recent(
lognos = [
"AH10173",
# None of the ACME challenge methods configured for this domain are suitable
"AH10056" # None of the ACME challenge methods configured for this domain are suitable
],
matches = [
r
'.*None of the ACME challenge methods configured for this domain are suitable.*'
]
)
def test_md_702_011(self, env):
domain = self.test_domain
domains = [domain,
"www." + domain]
#
# generate 1 MD and 1 vhost, map port 443 to where the server does not listen
conf = MDConf(env, admin=
"admin@" + domain)
conf.add(
"Protocols http/1.1 acme-tls/1")
conf.add_drive_mode(
"auto")
conf.add(
"MDPortMap https:99 http:99")
conf.add_md(domains)
conf.add_vhost(domains)
conf.install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
md = env.await_error(domain)
assert md[
"renewal"][
"errors"] > 0
#
# now the same with a 443 mapped to a supported port
conf = MDConf(env, admin=
"admin@" + domain)
conf.add(
"Protocols http/1.1 acme-tls/1")
conf.add_drive_mode(
"auto")
conf.add(
"MDCAChallenges tls-alpn-01")
conf.add(
"MDPortMap https:%s" % env.https_port)
conf.add_md(domains)
conf.add_vhost(domains)
conf.install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains)
assert env.await_completion([domain])
#
env.httpd_error_log.ignore_recent(
lognos = [
"AH10173",
# None of the ACME challenge methods configured for this domain are suitable
"AH10056" # None of the ACME challenge methods configured for this domain are suitable
],
matches = [
r
'.*None of the ACME challenge methods configured for this domain are suitable.*'
]
)
# test case: one MD with several dns names. sign up. remove the *first* name
# in the MD. restart. should find and keep the existing MD.
# See: https://github.com/icing/mod_md/issues/68
def test_md_702_030(self, env):
domain = self.test_domain
name_x =
"test-x." + domain
name_a =
"test-a." + domain
name_b =
"test-b." + domain
domains = [name_x, name_a, name_b]
#
# generate 1 MD and 2 vhosts
conf = MDConf(env, admin=
"admin@" + domain)
conf.add_md(domains)
conf.add_vhost(name_a)
conf.add_vhost(name_b)
conf.install()
#
# restart (-> drive), check that MD was synched and completes
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains)
assert env.await_completion([name_x])
env.check_md_complete(name_x)
#
# check: SSL is running OK
cert_a = env.get_cert(name_a)
assert name_a
in cert_a.get_san_list()
cert_b = env.get_cert(name_b)
assert name_b
in cert_b.get_san_list()
assert cert_a.same_serial_as(cert_b)
#
# change MD by removing 1st name
new_list = [name_a, name_b]
conf = MDConf(env, admin=
"admin@" + domain)
conf.add_md(new_list)
conf.add_vhost(name_a)
conf.add_vhost(name_b)
conf.install()
# restart, check that host still works and kept the cert
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(new_list)
status = env.get_certificate_status(name_a)
assert cert_a.same_serial_as(status[
'rsa'][
'serial'])
# test case: Same as 7030, but remove *and* add another at the same time.
# restart. should find and keep the existing MD and renew for additional name.
# See: https://github.com/icing/mod_md/issues/68
def test_md_702_031(self, env):
domain = self.test_domain
name_x =
"test-x." + domain
name_a =
"test-a." + domain
name_b =
"test-b." + domain
name_c =
"test-c." + domain
domains = [name_x, name_a, name_b]
#
# generate 1 MD and 2 vhosts
conf = MDConf(env, admin=
"admin@" + domain)
conf.add_md(domains)
conf.add_vhost(name_a)
conf.add_vhost(name_b)
conf.install()
#
# restart (-> drive), check that MD was synched and completes
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains)
assert env.await_completion([name_x])
env.check_md_complete(name_x)
#
# check: SSL is running OK
cert_a = env.get_cert(name_a)
assert name_a
in cert_a.get_san_list()
cert_b = env.get_cert(name_b)
assert name_b
in cert_b.get_san_list()
assert cert_a.same_serial_as(cert_b)
#
# change MD by removing 1st name and adding another
new_list = [name_a, name_b, name_c]
conf = MDConf(env, admin=
"admin@" + domain)
conf.add_md(new_list)
conf.add_vhost(name_a)
conf.add_vhost(name_b)
conf.install()
# restart, check that host still works and have new cert
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(new_list)
assert env.await_completion([name_a])
#
cert_a2 = env.get_cert(name_a)
assert name_a
in cert_a2.get_san_list()
assert not cert_a.same_serial_as(cert_a2)
# test case: create two MDs, move them into one
# see: <https://bz.apache.org/bugzilla/show_bug.cgi?id=62572>
def test_md_702_032(self, env):
domain = self.test_domain
name1 =
"server1." + domain
name2 =
"server2.b" + domain
# need a separate TLD to avoid rate limites
#
# generate 2 MDs and 2 vhosts
conf = MDConf(env, admin=
"admin@" + domain)
conf.add(
"MDMembers auto")
conf.add_md([name1])
conf.add_md([name2])
conf.add_vhost(name1)
conf.add_vhost(name2)
conf.install()
#
# restart (-> drive), check that MD was synched and completes
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md([name1])
env.check_md([name2])
assert env.await_completion([name1, name2])
env.check_md_complete(name2)
#
# check: SSL is running OK
cert1 = env.get_cert(name1)
assert name1
in cert1.get_san_list()
cert2 = env.get_cert(name2)
assert name2
in cert2.get_san_list()
#
# remove second md and vhost, add name2 to vhost1
conf = MDConf(env, admin=
"admin@" + domain)
conf.add(
"MDMembers auto")
conf.add_md([name1])
conf.add_vhost([name1, name2])
conf.install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md([name1, name2])
assert env.await_completion([name1])
#
cert1b = env.get_cert(name1)
assert name1
in cert1b.get_san_list()
assert name2
in cert1b.get_san_list()
assert not cert1.same_serial_as(cert1b)
# test case: one MD on a vhost with ServerAlias. Renew.
# Exchange ServerName and ServerAlias. Is the rename detected?
# See: https://github.com/icing/mod_md/issues/338
def test_md_702_033(self, env):
domain = self.test_domain
name_x =
"test-x." + domain
name_a =
"test-a." + domain
domains1 = [name_x, name_a]
#
# generate 1 MD and 2 vhosts
conf = MDConf(env, admin=
"admin@" + domain)
conf.add_md(domains=[name_x])
conf.add_vhost(domains=domains1)
conf.install()
#
# restart (-> drive), check that MD was synched and completes
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains1)
assert env.await_completion([name_x])
env.check_md_complete(name_x)
cert_x = env.get_cert(name_x)
#
# reverse ServerName and ServerAlias
domains2 = [name_a, name_x]
conf = MDConf(env, admin=
"admin@" + domain)
conf.add_md(domains=[name_a])
conf.add_vhost(domains=domains2)
conf.install()
# restart, check that host still works and kept the cert
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
status = env.get_certificate_status(name_a)
assert cert_x.same_serial_as(status[
'rsa'][
'serial'])
# test case: test "tls-alpn-01" challenge handling
def test_md_702_040(self, env):
domain = self.test_domain
domains = [domain,
"www." + domain]
#
# generate 1 MD and 1 vhost
conf = MDConf(env, admin=
"admin@" + domain)
conf.add(
"LogLevel core:debug")
conf.add(
"Protocols http/1.1 acme-tls/1")
conf.add_drive_mode(
"auto")
conf.add(
"MDCAChallenges tls-alpn-01")
conf.add_md(domains)
conf.add_vhost(domains=domains)
conf.install()
#
# restart (-> drive), check that MD was synched and completes
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains)
# check that acme-tls/1 is available for all domains
stat = env.get_md_status(domain)
assert stat[
"proto"][
"acme-tls/1"] == domains
assert env.await_completion([domain])
env.check_md_complete(domain)
#
# check SSL running OK
cert = env.get_cert(domain)
assert domain
in cert.get_san_list()
# test case: test "tls-alpn-01" without enabling 'acme-tls/1' challenge protocol
def test_md_702_041(self, env):
domain = self.test_domain
domains = [domain,
"www." + domain]
#
# generate 1 MD and 1 vhost
conf = MDConf(env, admin=
"admin@" + domain)
conf.add(
"LogLevel core:debug")
conf.add_drive_mode(
"auto")
conf.add(
"MDCAChallenges tls-alpn-01")
conf.add_md(domains)
conf.add_vhost(domains)
conf.install()
#
# restart (-> drive), check that MD job shows errors
# and that missing proto is detected
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains)
# check that acme-tls/1 is available for none of the domains
stat = env.get_md_status(domain)
assert stat[
"proto"][
"acme-tls/1"] == []
MDConf(env).install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.httpd_error_log.ignore_recent(matches=[
r
'.*None of offered challenge types for domain.*',
], lognos=[
"AH10056" # challenges not available
])
# test case: 2.4.40 mod_ssl stumbles over a SSLCertificateChainFile when installing
# a fallback certificate
@pytest.mark.skipif(HttpdTestEnv.get_ssl_module() !=
"mod_ssl", reason=
"only for mod_ssl")
def test_md_702_042(self, env):
domain = self.test_domain
dns_list = [domain]
conf = MDConf(env, admin=
"admin@" + domain)
conf.add(
"LogLevel core:debug")
cred = env.get_credentials_for_name(f
"test1.{env.http_tld}")[0]
conf.add(f
"SSLCertificateChainFile {cred.cert_file}")
conf.add_drive_mode(
"auto")
conf.add_md(dns_list)
conf.add_vhost(dns_list)
conf.install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
assert env.await_completion([domain])
# test case: test "tls-alpn-01" without enabling 'acme-tls/1' challenge protocol
# and fallback "http-01" configured, see https://github.com/icing/mod_md/issues/255
def test_md_702_043(self, env):
domain = self.test_domain
domains = [domain,
"www." + domain]
#
# generate 1 MD and 1 vhost
conf = MDConf(env, admin=
"admin@" + domain)
conf.add(
"LogLevel core:debug")
conf.add_drive_mode(
"auto")
conf.add(
"MDPortMap 80:%s" % env.http_port)
conf.add(
"MDCAChallenges tls-alpn-01 http-01")
conf.add_md(domains)
conf.add_vhost(domains)
conf.install()
#
# restart (-> drive), check that MD job shows errors
# and that missing proto is detected
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains)
# check that acme-tls/1 is available for none of the domains
stat = env.get_md_status(domain)
assert stat[
"proto"][
"acme-tls/1"] == []
# but make sure it completes nevertheless
assert env.await_completion([domain])
# test case: drive with using single challenge type explicitly
# and make sure that dns names not mapped to a VirtualHost also work
@pytest.mark.parametrize(
"challenge_type", [
"tls-alpn-01" # , "http-01",
])
def test_md_702_044(self, env, challenge_type):
domain = self.test_domain
md_domains = [domain,
"mail." + domain]
domains = [domain]
#
# generate 1 MD and 1 vhost
conf = MDConf(env, admin=
"admin@" + domain)
conf.add(
"Protocols http/1.1 acme-tls/1")
conf.add_drive_mode(
"auto")
conf.add(f
"MDCAChallenges {challenge_type}")
conf.add_md(md_domains)
conf.add_vhost(domains)
conf.install()
#
# restart (-> drive), check that MD was synched and completes
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(md_domains)
assert env.await_completion([domain])
env.check_md_complete(domain)
#
# check SSL running OK
cert = env.get_cert(domain)
assert md_domains[0]
in cert.get_san_list()
assert md_domains[1]
in cert.get_san_list()
# Make a setup using the base server. It will use http-01 challenge.
def test_md_702_050(self, env):
domain = self.test_domain
conf = MDConf(env, admin=f
"admin@{domain}")
conf.add(f
"""
MDBaseServer on
ServerName {domain}
""")
conf.add_md([domain])
conf.install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
assert env.await_completion([domain])
# Make a setup using the base server without http:, will fail.
def test_md_702_051(self, env):
domain = self.test_domain
conf = MDConf(env, admin=f
"admin@{domain}")
conf.add(f
"""
MDBaseServer on
MDPortMap http:-
ServerName {domain}
""")
conf.add_md([domain])
conf.install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
assert env.await_error(domain)
#
env.httpd_error_log.ignore_recent(
lognos = [
"AH10173",
# None of the ACME challenge methods configured for this domain are suitable
"AH10056" # None of the ACME challenge methods configured for this domain are suitable
],
matches = [
r
'.*None of the ACME challenge methods configured for this domain are suitable.*'
]
)
# Make a setup using the base server without http:, but with acme-tls/1, should work.
def test_md_702_052(self, env):
domain = self.test_domain
conf = MDConf(env, std_vhosts=
False, admin=f
"admin@{domain}")
conf.add([
"MDBaseServer on",
"MDPortMap http:-",
"Protocols h2 http/1.1 acme-tls/1",
f
"ServerName {domain}",
"",
" SSLEngine on",
"",
"",
f
" TLSEngine {env.https_port}",
"",
])
conf.add_md([domain])
conf.install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
stat = env.get_md_status(domain, via_domain=env.http_addr, use_https=
False)
assert stat[
"proto"][
"acme-tls/1"] == [domain]
assert env.await_completion([domain], via_domain=env.http_addr, use_https=
False)
# Test a domain name longer than 64 chars, but components < 64, see #227
# Background: DNS has an official limit of 253 ASCII chars and components must be
# of length [1, 63].
# However the CN in a certificate is restricted too, see
# <https://github.com/letsencrypt/boulder/issues/2093>.
@pytest.mark.skipif(MDTestEnv.is_pebble(), reason=
"pebble differs here from boulder")
@pytest.mark.parametrize(
"challenge_type", [
"tls-alpn-01",
"http-01"
])
def test_md_702_060(self, env, challenge_type):
domain = self.test_domain
# use only too long names, this is expected to fail:
# see <https://github.com/jetstack/cert-manager/issues/1462>
long_domain = (
"x" * (65 - len(domain))) + domain
domains = [long_domain,
"www." + long_domain]
conf = MDConf(env, admin=
"admin@" + domain)
conf.add(
"Protocols http/1.1 acme-tls/1")
conf.add_drive_mode(
"auto")
conf.add(f
"MDCAChallenges {challenge_type}")
conf.add_md(domains)
conf.add_vhost(domains)
conf.install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
env.check_md(domains)
assert env.await_error(long_domain)
# add a short domain to the SAN list, the CA should now use that one
# and issue a cert.
long_domain = (
"y" * (65 - len(domain))) + domain
domains = [long_domain,
"www." + long_domain,
"xxx." + domain]
conf = MDConf(env, admin=
"admin@" + domain)
conf.add(
"Protocols http/1.1 acme-tls/1")
conf.add_drive_mode(
"auto")
conf.add(f
"MDCAChallenges {challenge_type}")
conf.add_md(domains)
conf.add_vhost(domains)
conf.install()
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
assert env.await_completion([long_domain])
env.check_md_complete(long_domain)
#
# check SSL running OK
cert = env.get_cert(long_domain)
assert long_domain
in cert.get_san_list()
# test case: fourth level domain
def test_md_702_070(self, env):
domain = self.test_domain
name_a =
"one.test." + domain
name_b =
"two.test." + domain
domains = [name_a, name_b]
#
# generate 1 MD and 2 vhosts
conf = MDConf(env)
conf.add_admin(
"admin@" + domain)
conf.add_md(domains)
conf.add_vhost(name_a)
conf.install()
#
# restart (-> drive), check that MD was synched and completes
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
assert env.await_completion(domains)
env.check_md_complete(domains[0])
# test case: fifth level domain
def test_md_702_071(self, env):
domain = self.test_domain
name_a =
"one.more.test." + domain
name_b =
"two.more.test." + domain
domains = [name_a, name_b]
#
# generate 1 MD and 2 vhosts
conf = MDConf(env)
conf.add_admin(
"admin@" + domain)
conf.add_md(domains)
conf.add_vhost(name_a)
conf.install()
#
# restart (-> drive), check that MD was synched and completes
assert env.apache_restart() == 0, f
'{env.apachectl_stderr}'
assert env.await_completion(domains)
env.check_md_complete(domains[0])