すべてのプロダクト
Search
ドキュメントセンター

MaxCompute:IPを使用したHTTPSサービスへのアクセス

最終更新日:Feb 13, 2025

リモートVPCサービスは、ドメイン名のみによるアクセスをサポートします。 IPを使用した直接アクセスはエラーを引き起こし、リクエストが失敗します。 このトピックでは、IPアドレスを介してHTTPSサービスにアクセスするためのドメイン名をリクエストホストに追加し、SparkやUDFなどのタスクのリモートアクセス要件を満たすことで、この問題を解決する方法について説明します。

IPを使用したHTTPSサービスへの直接アクセスに失敗

問題の内容

HTTPS機能は、KMSやOSS for SparkまたはUDFタスクなどのリモートVPCサービスにアクセスする場合に不可欠です。 ただし、IPを使用してこれらのサービスに直接アクセスすると、次のようなエラーメッセージが表示されます。

SSL: no alternative certificate subject name matches target host name '47.116.XX.XX'
More details here: https://curl.haxx.se/docs/sslcerts.html 
curl failed to verify the legitimacy of the server and therefore could not establish a secure connection to it. 
To learn more about this situation and how to fix it, please visit the web page mentioned above.

解決策

IPを使用してHTTPSサービスに直接アクセスする場合のSSL証明書の検証失敗の問題を解決するには、ドメイン名をリクエストホストに追加します。

1. リモートサービスのIP情報を取得します。

pingコマンドを使用する

WindowsまたはLinuxコンソールで次のコマンドを入力して、リモートサービスIPを取得します。

ping service.cn-shanghai-vpc.maxcompute.aliyun-inc.com
  • Windows環境で返される結果は次のとおりです。

    tt

  • Linux環境で返される結果は次のとおりです。

    yy

digコマンドを使用する

  1. 環境にBind-utilsをインストールします。

    • Windows

      BIND9.17.12.x64.zipをダウンロードし、D:\install\BIND9.17.12.x64などの指定されたディレクトリに展開し、このパスをWindowsのpath環境変数に追加します。

    • Linux (CentOS)

      Linuxコンソールでsudo yum install bind-utilsコマンドを実行してインストールします。

  2. コンソールで次のコマンドを実行します。

    dig service.cn-shanghai-vpc.maxcompute.aliyun-inc.com

    返される結果は次のとおりです。

    Windows

    ppp

    Linux

    123h

2. IP情報を設定します。

次のコードサンプルを参照して、使用しているPythonバージョンに基づいて、リクエストのaccess_urlにIP情報を追加します。 タスクを展開する前に、対応するネットワーク環境でリモートアクセステストを実行します。

  • Python 2

    # _*_ coding: utf-8 _*_
    # only for python2
    import requests
    from urlparse import urlparse
    
    class HostHeaderSSLAdapter(requests.adapters.HTTPAdapter):
        def __init__(self, resolved_ip):
            super(HostHeaderSSLAdapter,self).__init__()
            self.resolved_ip = resolved_ip
    
        def send(self, request, **kwargs):
            connection_pool_kwargs = self.poolmanager.connection_pool_kw
            result = urlparse(request.url)
    
            if result.scheme == 'https' and self.resolved_ip:
                request.url = request.url.replace(
                    'https://' + result.hostname,
                    'https://' + self.resolved_ip,
                )
                connection_pool_kwargs['assert_hostname'] = result.hostname
                request.headers['Host'] = result.hostname
            else:
                connection_pool_kwargs.pop('assert_hostname', None)
    
            return super(HostHeaderSSLAdapter, self).send(request, **kwargs)
    
    def access_url(url, resolved_ip):
        session = requests.Session()
        # Get the domain name part from the url
        parsed_url = urlparse(url)
        hostname = parsed_url.hostname
    
        session.mount('https://'+hostname, HostHeaderSSLAdapter(resolved_ip))
        try:
            r = session.get(url)
        except Exception as e:
            print("err : "+ str(e))
        else:
            if r.status_code != 200:
                print("not 200 " + ",resp : "+ r.text)
            else:
                print("success" + ",resp : "+ r.text)
    
    if __name__ == "__main__":
        # Retrieve IP through the dig command, need to dig in VPC environment
        # VPC address test
        # access_url("https://service.cn-shanghai-vpc.maxcompute.aliyun-inc.com", "100.103.104.45")
        # Public network address test
        access_url("https://service.cn-shanghai.maxcompute.aliyun.com", "47.116.XX.XX")
  • Python 3

    # _*_ coding: utf-8 _*_
    import requests
    from urllib.parse import urlparse 
    
    class HostHeaderSSLAdapter(requests.adapters.HTTPAdapter):
        def __init__(self, resolved_ip):
            super().__init__()                                        
            self.resolved_ip = resolved_ip
    
        def send(self, request, **kwargs):
            connection_pool_kwargs = self.poolmanager.connection_pool_kw
            result = urlparse(request.url)
    
            if result.scheme == 'https' and self.resolved_ip:
                request.url = request.url.replace(
                    'https://' + result.hostname,
                    'https://' + self.resolved_ip,
                )
                connection_pool_kwargs['server_hostname'] = result.hostname  
                # overwrite the host header
                request.headers['Host'] = result.hostname
            else:
                # these headers from a previous request may have been left
                connection_pool_kwargs.pop('server_hostname', None)           
            return super().send(request, **kwargs)
    
    def access_url(url, resolved_ip):
        session = requests.Session()
        # Get the domain name part from the url
        parsed_url = urlparse(url)
        hostname = parsed_url.hostname
    
        session.mount('https://'+hostname, HostHeaderSSLAdapter(resolved_ip))
        try:
            r = session.get(url)
        except Exception as e:
            print("err : "+ str(e))
        else:
            if r.status_code != 200:
                print("not 200 " + ",resp : "+ r.text)
            else:
                print("success" + ",resp : "+ r.text)
    
    if __name__ == "__main__":
        # Retrieve IP through the dig command, need to dig in VPC environment
        # VPC address test
        # access_url("https://service.cn-shanghai-vpc.maxcompute.aliyun-inc.com", "100.103.104.45")
        # Public network address test
        access_url("https://service.cn-shanghai.maxcompute.aliyun.com", "47.116.XX.XX")

テスト結果

説明

VPCネットワーク内のインスタンスサービスにアクセスするには、VPCネットワークでPython環境を設定し、テスト用のサービスリンクとIPアドレスを置き換えます。

  • パブリックネットワークを介してMaxComputeサービスにローカルにアクセスします。

    fartestsss

  • パブリックネットワークを介してLinuxを実行しているElastic Compute serviceインスタンスのMaxComputeサービスにアクセスします。

    yyyrtqerewr