リモート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.comWindows環境で返される結果は次のとおりです。

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

digコマンドを使用する
環境にBind-utilsをインストールします。
Windows
BIND9.17.12.x64.zipをダウンロードし、
D:\install\BIND9.17.12.x64などの指定されたディレクトリに展開し、このパスをWindowsのpath環境変数に追加します。Linux (CentOS)
Linuxコンソールで
sudo yum install bind-utilsコマンドを実行してインストールします。
コンソールで次のコマンドを実行します。
dig service.cn-shanghai-vpc.maxcompute.aliyun-inc.com返される結果は次のとおりです。
Windows

Linux

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サービスにローカルにアクセスします。

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