簡體   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