Exemplo n.º 1
0
def handler(event: typing.Any, context: typing.Any) -> typing.Mapping[str, typing.Any]:
    client = boto3.client("s3")
    storage = S3Storage(bucket=S3Storage.Bucket(os.environ["BUCKET"], client))
    authenticators = [HTTP01Authenticator(storage=storage)]
    params: typing.Any = {
        "acme_account_email": os.environ["ACME_ACCOUNT_EMAIL"],
        "acme_directory_url": os.environ["ACME_DIRECTORY_URL"],
        "storage": storage,
    }
    if event["action"] == "renew":
        certificates = [
            certificate for certificate, _ in find_certificates_to_renew(storage)
        ]
        failure = []
        for certificate in certificates:
            try:
                renew(certificate=certificate, authenticators=authenticators, **params)
            except Exception as exc:
                logger.error(str(exc))
                failure.append(certificate.name)
        if len(failure) == len(certificates):
            raise RuntimeError(f"All renew operations failed: {failure}")
    elif event["action"] == "issue":
        issue(domains=[event["domain"]], authenticators=authenticators, **params)
    elif event["action"] == "revoke":
        cert = storage.get_certificate(name=event["domain"])
        assert cert
        revoke(certificate=cert, **params)

    return {"statusCode": 200}
Exemplo n.º 2
0
def test_san_mixed(get_dns_txt_records, acme_directory_url, minio_bucket,
                   pebble, full_infra, r53):
    storage = S3Storage(bucket=minio_bucket)
    domains = ["*.example.com", "fake.com", "www.fake.com", "my.com"]

    dns_auth = Route53Authenticator(r53, {
        "example.com": "ZONEID2",
        "www.fake.com": "ZONEID2"
    })
    http_auth = HTTP01Authenticator(storage=storage)
    issue(
        domains=domains,
        storage=storage,
        acme_directory_url=acme_directory_url,
        acme_account_email="*****@*****.**",
        authenticators=[dns_auth, http_auth],
    )
    pem_data = storage.get_certificate(domains=domains).fullchain
    assert pem_data
    cert = x509.load_pem_x509_certificate(pem_data, default_backend())
    assert cert.subject.rfc4514_string() == f"CN={domains[0]}"
    sans = cert.extensions.get_extension_for_class(
        x509.extensions.SubjectAlternativeName).value
    assert [x.value for x in sans] == domains
    valid_from = cert.not_valid_before
    assert datetime.datetime.now() > valid_from
Exemplo n.º 3
0
def test_s3_find_expired(bucket, acm, moto_certs):
    key_pem, fullchain_pem = moto_certs
    storage = S3Storage(bucket=bucket)
    storage.subscribe(ACMStorageObserver(acm=acm))
    certificate = Certificate(["*.example.com"], private_key=key_pem)
    certificate.set_fullchain(fullchain_pem)
    storage.save_certificate(certificate)
    now = datetime.datetime.utcnow().replace(tzinfo=tzutc())
    assert not list(find_certificates_to_renew(storage))
    with time_machine.travel(now + datetime.timedelta(days=59)):
        assert not list(find_certificates_to_renew(storage))
    with time_machine.travel(now - datetime.timedelta(days=10)):
        assert not list(find_certificates_to_renew(storage))
    with time_machine.travel(now + datetime.timedelta(days=61)):
        certs = list(find_certificates_to_renew(storage))
        assert len(certs) == 1
        assert certs[0][0].name == "*.example.com"
    with time_machine.travel(now + datetime.timedelta(days=356)):
        certs = list(find_certificates_to_renew(storage))
        assert len(certs) == 1
        assert certs[0][0].name == "*.example.com"
    with time_machine.travel(now + datetime.timedelta(days=90)):
        certificate = Certificate(["new.example.com"], private_key=key_pem)
        certificate.set_fullchain(fullchain_pem)
        storage.save_certificate(certificate)
        certs = list(find_certificates_to_renew(storage))
        assert len(certs) == 1
    with time_machine.travel(now + datetime.timedelta(days=180)):
        certs = list(find_certificates_to_renew(storage))
        assert len(certs) == 2
def test_dns01(get_dns_txt_records, acme_directory_url, minio_bucket, pebble,
               disable_ssl, r53):
    storage = S3Storage(bucket=minio_bucket)
    domain_name = "*.example.com"

    auth = Route53Authenticator(
        r53,
        {
            "my.example.com": "ZONEID1",
            "example.com": "ZONEID2",
            "my.example.org": "ZONEID0",
        },
    )
    issue(
        domains=[domain_name],
        storage=storage,
        acme_directory_url=acme_directory_url,
        acme_account_email="*****@*****.**",
        authenticators=[auth],
    )
    pem_data = storage.get_certificate(domains=[domain_name]).fullchain
    assert pem_data
    cert = x509.load_pem_x509_certificate(pem_data, default_backend())
    assert cert.subject.rfc4514_string() == f"CN={domain_name}"
    valid_from = cert.not_valid_before
    assert datetime.datetime.now() > valid_from
Exemplo n.º 5
0
def test_load_balancer_redirect(minio_bucket, load_balancer, acm):
    storage = S3Storage(bucket=minio_bucket)
    storage.subscribe(ACMStorageObserver(acm=acm))
    storage.set_validation("/.well-known/acme-challenge/randomkey",
                           b"secretstring")
    r = urllib.request.urlopen(load_balancer["url"] +
                               "/.well-known/acme-challenge/randomkey")
    assert r.status == 200
    assert r.read() == b"secretstring"
Exemplo n.º 6
0
def test_acm_issue_renew_revoke(minio_bucket, full_infra, acm,
                                acme_directory_url):
    storage = S3Storage(bucket=minio_bucket)
    observer = ACMStorageObserver(acm=acm)
    storage.subscribe(observer)
    domain_name = "my3.example.com"

    auth = HTTP01Authenticator(storage=storage)
    issue(
        domains=[domain_name],
        storage=storage,
        acme_directory_url=acme_directory_url,
        acme_account_email="*****@*****.**",
        authenticators=[auth],
    )
    certificate = storage.get_certificate(domains=[domain_name])
    pem_data = certificate.fullchain
    assert pem_data
    cert = x509.load_pem_x509_certificate(pem_data, default_backend())
    assert cert.subject.rfc4514_string() == f"CN={domain_name}"
    valid_from = cert.not_valid_before
    assert datetime.datetime.now() > valid_from

    acm_arn = observer._acm_arn_resolver.get(domain_name)
    assert acm_arn

    renew(
        certificate=certificate,
        storage=storage,
        acme_directory_url=acme_directory_url,
        acme_account_email="*****@*****.**",
        authenticators=[auth],
    )
    pem_data = storage.get_certificate(domains=[domain_name]).fullchain
    assert pem_data
    cert = x509.load_pem_x509_certificate(pem_data, default_backend())
    assert cert.subject.rfc4514_string() == f"CN={domain_name}"
    assert cert.not_valid_before > valid_from
    assert datetime.datetime.now() > cert.not_valid_before

    new_acm_arn = observer._acm_arn_resolver.get(domain_name)
    assert acm_arn == new_acm_arn

    revoke(
        certificate=certificate,
        storage=storage,
        acme_directory_url=acme_directory_url,
        acme_account_email="*****@*****.**",
    )
    assert storage.get_certificate(domains=[domain_name]) is None
Exemplo n.º 7
0
def _minio_bucket(minio, minio_boto3_settings, minio_settings):
    client = boto3.client("s3", **minio_boto3_settings)
    name = minio_settings["BUCKET"]
    client.create_bucket(Bucket=name)
    policy = {
        "Version":
        "2012-10-17",
        "Statement": [{
            "Sid":
            "AddPerm",
            "Effect":
            "Allow",
            "Principal":
            "*",
            "Action": ["s3:GetObject"],
            "Resource": [f"arn:aws:s3:::{name}/.well-known/acme-challenge/*"],
        }],
    }
    client.put_bucket_policy(Bucket=name, Policy=json.dumps(policy))
    return S3Storage.Bucket(name, client)
Exemplo n.º 8
0
def bucket(s3, minio_settings):
    name = minio_settings["BUCKET"]
    s3.create_bucket(
        Bucket=name,
        CreateBucketConfiguration={"LocationConstraint": "ap-southeast-2"})
    policy = {
        "Version":
        "2012-10-17",
        "Statement": [{
            "Sid":
            "AddPerm",
            "Effect":
            "Allow",
            "Principal":
            "*",
            "Action": ["s3:GetObject"],
            "Resource": [f"arn:aws:s3:::{name}/.well-known/acme-challenge/*"],
        }],
    }
    s3.put_bucket_policy(Bucket=name, Policy=json.dumps(policy))
    return S3Storage.Bucket(name, s3)
Exemplo n.º 9
0
def test_s3_mixin_ops(bucket):
    storage = S3Storage(bucket=bucket)
    key = "keys/example.com"
    assert storage._get(key) is None
    storage._set(key, b"mybytes")
    assert storage._get(key) == b"mybytes"