简体   繁体   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?

I have read every ounce of documentation I could find related to this topic.我已经阅读了所有我能找到的与该主题相关的文档。 I've been using the boto3 Python client to work with AWS to register a new domain and verify it to be used with the AWS Simple Email Service (SES).我一直在使用 boto3 Python 客户端与 AWS 一起注册一个新域并验证它是否与 AWS 简单 Email 服务 (SES) 一起使用。

This is an entirely painless task in just a few clicks with the GUI:这是一项完全轻松的任务,只需在 GUI 中单击几下:

在此处输入图像描述

And I thought, reading the SES boto3 documentation , I could achieve the same thing via API with the Python client.我想,阅读SES boto3 文档,我可以通过 API 和 Python 客户端实现同样的事情。

But nothing happens.但是没有任何反应。 I get no error.我没有错误。 No indication appears in the GUI that the verification is pending (the way it does when done through the GUI). GUI 中没有指示验证正在等待(通过 GUI 完成时的方式)。 Even after 72 hours, nothing changes.即使在 72 小时后,也没有任何变化。 But when I do it in the GUI, it works pretty quickly, so presumably I just missed some important API step.但是当我在 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: 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.

What am I missing here?我在这里错过了什么? Is what I'm trying to do a simple matter of something I missed in the documentation?我想做的是我在文档中遗漏的简单问题吗? Or is this not even viable purely via API in AWS?还是仅通过 AWS 中的 API 甚至不可行? I suspect the former.我怀疑是前者。

Maybe I need to handle the record assignment process manually with the Route53 API?也许我需要使用 Route53 API 手动处理记录分配过程? I'd really appreciate an example of what that would like if so.如果是这样的话,我真的很感激一个例子。 Otherwise just a hint that this is a requirement, and that SES will not do it automatically like with the GUI functionality, would be helpful to know.否则,只要提示这是一项要求,并且 SES 不会像使用 GUI 功能那样自动执行此操作,就会很有帮助。

You are already done with the configuration, but the same time you have to add the same key-value pair against the domain and add the key accordingly.您已经完成了配置,但同时您必须针对域添加相同的键值对并相应地添加键。

it depends if your NS is with Route53 and making that configuration with IDE than, your data with automatically pushed to that service, or if you using SDK or adding entries via API than parallel you have to add that key(DKIM entries to the given zone via Route53 APIs) against the given zone-id这取决于你的 NS 是否使用 Route53 并使用 IDE 进行配置,你的数据是否自动推送到该服务,或者如果你使用 SDK 或通过 API 添加条目比并行你必须添加该密钥(DKIM 条目到给定区域通过 Route53 API)针对给定的区域 ID

but if you're not working with Route53 than you must add the given key-value of DKIM entries with the NS Handler.但如果您不使用 Route53,则必须使用 NS 处理程序添加 DKIM 条目的给定键值。

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

相关问题 如何在 python 中使用 boto3 更新 AWS Gamelift 脚本? - How do I update an AWS Gamelift script with boto3 in python? boto3 如何通过 python 脚本使用 AWS SSM 服务安装 cloud watch agent - boto3 How to install cloud watch agent using AWS SSM service through python script 蟒蛇 | Boto3 - AWS SNS 电子邮件格式问题 - Python | Boto3 - AWS SNS Email formatting issue AWS SES(简单电子邮件服务)记录发送的电子邮件收件人地址 - AWS SES(Simple Email Service) logging sent email recipients address AWS SES 简单 email 服务,Zend 超时错误 email - AWS SES simple email service, time out error with Zend email 与通过 AWS cli 执行的查询相比,通过 boto3 python 客户端执行的 Athena 查询给出的结果更小 - Athena query executed through boto3 python client gives smaller result compared to query executed through AWS cli 如何使用 boto3 轮换我的 AWS IAM 用户访问权限和密钥? - How do I rotate my AWS IAM user access and secret key using boto3? 使用 route53domains 的 boto3 分页 - boto3 pagination with route53domains 如何将 AWS Amplify 应用程序添加为 AWS Route53 中托管域的子域? - How to add an AWS Amplify application as subdomain for domain hosted in AWS Route53? 为在 AWS Route 53 上注册的 Netlify 子域配置 HTTPS - Configuring HTTPS for Netlify subdomain registered on AWS Route 53
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM