繁体   English   中英

如何仅通过 Python 客户端 boto3 使用 AWS 简单 Email 服务 (SES) 验证在 AWS Route 53 中注册的域?

[英]How do I verify a domain registered in AWS Route 53 with AWS Simple Email Service (SES) purely through the Python client, boto3?

我已经阅读了所有我能找到的与该主题相关的文档。 我一直在使用 boto3 Python 客户端与 AWS 一起注册一个新域并验证它是否与 AWS 简单 Email 服务 (SES) 一起使用。

这是一项完全轻松的任务,只需在 GUI 中单击几下:

在此处输入图像描述

我想,阅读SES boto3 文档,我可以通过 API 和 Python 客户端实现同样的事情。

但是没有任何反应。 我没有错误。 GUI 中没有指示验证正在等待(通过 GUI 完成时的方式)。 即使在 72 小时后,也没有任何变化。 但是当我在 GUI 中执行它时,它运行得非常快,所以大概我只是错过了一些重要的 API 步骤。

%pip install boto3 # a Jupyter-ism
import boto3
import time

class Domain:
    
    # AWS Route 53 Domains Documentation:
    
    # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/route53domains.html#Route53Domains.Client.get_operation_detail
    
    def __init__(self, static_domain=False): # identity: Identity
        self.client = boto3.client('route53domains')
        
        if static_domain:
            
            domain_list_response = self.client.list_domains()
            print(domain_list_response)
            domain_owned = False
            
            for domain in domain_list_response['Domains']:
                if domain['DomainName'] == static_domain:
                    domain_owned = True
                    
            if domain_owned:
                print('Domain already owned...')
                self.name = static_domain
                
            else:
                availability_response = self.client.check_domain_availability(
                    DomainName=static_domain
                )

                first_name = 'First' # identity.fname
                last_name = 'Last' # identity.lname
                org_name = 'Testing123' # identity.org
                address = '123 Testing Drive' # idenity.addr
                city = 'TestingCity' # identity.city
                state = 'TestingState' # identity.state_code
                country = 'US' # identity.country_code
                zip_code = '12345' # identity.zip_code
                phone = '+1.1234567890' # identity.phone
                email = f'admin@{static_domain}'

                if availability_response['Availability'] == 'AVAILABLE':
                    print('Domain available...')

                    registration_response = self.client.register_domain(
                        DomainName=static_domain,
                        DurationInYears=1,
                        AutoRenew=False,
                        AdminContact={
                            'FirstName': first_name,
                            'LastName': last_name,
                            'ContactType': 'PERSON',
                            'OrganizationName': org_name,
                            'AddressLine1': address,
                            'City': city,
                            'State': state,
                            'CountryCode': country,
                            'ZipCode': zip_code,
                            'PhoneNumber': phone,
                            'Email': email
                        },
                        RegistrantContact={
                            'FirstName': first_name,
                            'LastName': last_name,
                            'ContactType': 'PERSON',
                            'OrganizationName': org_name,
                            'AddressLine1': address,
                            'City': city,
                            'State': state,
                            'CountryCode': country,
                            'ZipCode': zip_code,
                            'PhoneNumber': phone,
                            'Email': email
                        },
                        TechContact={
                            'FirstName': first_name,
                            'LastName': last_name,
                            'ContactType': 'PERSON',
                            'OrganizationName': org_name,
                            'AddressLine1': address,
                            'City': city,
                            'State': state,
                            'CountryCode': country,
                            'ZipCode': zip_code,
                            'PhoneNumber': phone,
                            'Email': email
                        },
                        PrivacyProtectAdminContact=False,
                        PrivacyProtectRegistrantContact=False,
                        PrivacyProtectTechContact=False
                    )
                    print(registration_response)
                    operation_id = registration_response['OperationId']
                    print(operation_id)
                    operation_detail_response = self.client.get_operation_detail(
                        OperationId=operation_id
                    )
                    print(operation_detail_response)
                    while operation_detail_response['Status'] == 'IN_PROGRESS':
                        time.sleep(10)
                        operation_detail_response = self.client.get_operation_detail(
                            OperationId=operation_id
                        )
                        print(operation_detail_response)
                        if operation_detail_response['Status'] == 'IN_PROGRESS':
                            print('Domain registration in progress...')
                        else:
                            print('Domain registration successful...')

        else:
            print('dynamic domain generation not yet supported')

class Inbox:
    def __init__(self, domain, username: str):
        self.client = boto3.client('ses')
        self.domain = domain
        self.username = username
        self.address = f'{self.username}@{self.domain.name}'
        print(f'Inbox ({self.domain.name}) ready...')
        
        verify_domain_id_response = self.client.verify_domain_identity(
            Domain=self.domain.name
        )
        print('verify_domain_id_response[\'VerificationToken\']', verify_domain_id_response['VerificationToken'])
        print('')
        
        domain_verified = False
        while domain_verified == False:
            get_identity_verification_attributes_response = self.client.get_identity_verification_attributes(
                Identities=[
                    self.domain.name,
                ]
            )
            print('get_identity_verification_attributes_response', get_identity_verification_attributes_response)
            print('')

            for identity in get_identity_verification_attributes_response['VerificationAttributes']:
                status = get_identity_verification_attributes_response['VerificationAttributes'][identity]['VerificationStatus']
                if status == 'Success':
                    domain_verified = True
                else:
                    print('Domain verification status:', status)
                    print('This could take up to 72 hours. Feel free to close this notebook and re-execute the code from this cell later. The process is happening on AWS\'s end and will not be interrupted. Once verified, re-executing the code won\'t reset the status, don\'t worry.')
                    time.sleep(100)
                    
        verify_domain_dkim_response = self.client.verify_domain_dkim(
            Domain=self.domain.name
        )
        print('verify_domain_dkim_response[\'DkimTokens\']', verify_domain_dkim_response['DkimTokens'])
        print('')
        
        enable_id_dkim_response = self.client.set_identity_dkim_enabled(
            Identity=self.domain.name,
            DkimEnabled=True
        )
        print('enable_id_dkim_response', enable_id_dkim_response)
        print('')

        # ... snip ... code to create actual inboxes + send & receive emails
        # from domain
        
        print('Inbox verified...')

domain = Domain(static_domain='testing.com')
inbox = Inbox(domain=domain, username='admin')

Output:

{'Domains': [{'DomainName': '... snip ...', 'AutoRenew': False, 'TransferLock': False, 'Expiry': datetime.datetime(2024, 1, 21, 16, 51, 56, tzinfo=tzlocal())}], 'ResponseMetadata': {'RequestId': '... snip ...', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '... snip ...', 'content-type': 'application/x-amz-json-1.1', 'content-length': '104', 'date': 'Mon, 23 Jan 2023 02:31:27 GMT'}, 'RetryAttempts': 0}}
Domain already owned...
Inbox (... snip ...) ready...
verify_domain_id_response['VerificationToken'] ... snip ...

get_identity_verification_attributes_response {'VerificationAttributes': {'... snip ...': {'VerificationStatus': 'Pending', 'VerificationToken': '... snip ...'}}, 'ResponseMetadata': {'RequestId': '... snip ...', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Mon, 23 Jan 2023 02:31:27 GMT', 'content-type': 'text/xml', 'content-length': '639', 'connection': 'keep-alive', 'x-amzn-requestid': '... snip ...'}, 'RetryAttempts': 0}}

Domain verification status: Pending
This could take up to 72 hours. Yes, really. Feel free to close this notebook and re-execute the code from this cell later. The process is happening on AWS's end and will not be interrupted. Once verified, re-executing the code won't reset the status, don't worry.

我在这里错过了什么? 我想做的是我在文档中遗漏的简单问题吗? 还是仅通过 AWS 中的 API 甚至不可行? 我怀疑是前者。

也许我需要使用 Route53 API 手动处理记录分配过程? 如果是这样的话,我真的很感激一个例子。 否则,只要提示这是一项要求,并且 SES 不会像使用 GUI 功能那样自动执行此操作,就会很有帮助。

您已经完成了配置,但同时您必须针对域添加相同的键值对并相应地添加键。

这取决于你的 NS 是否使用 Route53 并使用 IDE 进行配置,你的数据是否自动推送到该服务,或者如果你使用 SDK 或通过 API 添加条目比并行你必须添加该密钥(DKIM 条目到给定区域通过 Route53 API)针对给定的区域 ID

但如果您不使用 Route53,则必须使用 NS 处理程序添加 DKIM 条目的给定键值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM