远程VPC服务仅支持使用域名访问,直接使用IP访问会导致错误使请求失败。本文将介绍通过将域名添加到请求Host中,以便通过IP地址访问HTTPS服务,来满足Spark或UDF等任务的远程访问需求。
直接使用IP访问HTTPS服务失败
报错信息
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.
问题描述
Spark或UDF等任务,访问远程VPC服务,比如KMS、OSS等。在此过程中需要使用HTTPS功能,如果直接通过IP来访问对端服务会报上述错误信息。
解决方案
将域名添加到请求的host中,以解决通过IP直接访问HTTPS服务时所遇到的IP无法通过SSL证书验证的问题。
1. 获取远程服务的IP信息。
ping命令获取
在Windows或Linux的控制台,直接输入如下指令,并获取远程服务IP。
ping service.cn-shanghai-vpc.maxcompute.aliyun-inc.com
-
Windows环境返回结果如下:
PS C:\Users\xxx> ping service.cn-shanghai-vpc.maxcompute.aliyun-inc.com Ping service.cn-shanghai-vpc.maxcompute.aliyun-inc.com [100.103.104.45] xxx -
Linux环境返回结果如下:
[root@iZbxxx ~]# ping service.cn-shanghai-vpc.maxcompute.aliyun-inc.com PING service.cn-shanghai-vpc.maxcompute.aliyun-inc.com (100.103.104.45) 56(84) bytes of data.
dig命令获取
-
在Windows环境或Linux环境下安装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.comWindows环境
PS C:\Users\xxx> dig service.cn-shanghai-vpc.maxcompute.aliyun-inc.com ; <<>> DiG 9.17.12 <<>> service.cn-shanghai-vpc.maxcompute.aliyun-inc.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49974 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4000 ;; QUESTION SECTION: ;service.cn-shanghai-vpc.maxcompute.aliyun-inc.com. IN A ;; ANSWER SECTION: service.cn-shanghai-vpc.maxcompute.aliyun-inc.com. 1 IN A 100.103.104.45 ;; Query time: 4 msec ;; SERVER: 10.61.150.xxx ;; WHEN: Wed Jan 08 14xxxLinux环境
[root@iZbxxx ~]# dig service.cn-shanghai-vpc.maxcompute.aliyun-inc.com ; <<>> DiG 9.11.4-P2-RedHat-9.11.4 <<>> service.cn-shanghai-vpc.maxcompute.aliyun-inc.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36725 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;service.cn-shanghai-vpc.maxcompute.aliyun-inc.com. IN A ;; ANSWER SECTION: service.cn-shanghai-vpc.maxcompute.aliyun-inc.com. 1 IN A 100.103.104.45 ;; Query time: 2 msec ;; SERVER: 100.100.2.xxx ;; WHEN: Wed Jan 08 14xxx
2. 配置IP信息。
您可以根据Python不同版本,参考如下代码,在发送请求的access_url中添加IP信息。在正式发布任务之前,可先在对应网络环境进行远程访问测试。
-
python2
# _*_ 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() # 从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__": # ip通过dig域名获取,需要在vpc环境内dig # vpc地址测试 #access_url("https://service.cn-shanghai-vpc.maxcompute.aliyun-inc.com", "100.103.104.45") # 公网地址测试 access_url("https://service.cn-shanghai.maxcompute.aliyun.com", "47.116.XX.XX") -
python3
# _*_ 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: # theses 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() # 从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__": # ip通过dig域名获取,需要在vpc环境内dig # vpc地址测试 #access_url("https://service.cn-shanghai-vpc.maxcompute.aliyun-inc.com", "100.103.104.45") # 公网地址测试 access_url("https://service.cn-shanghai.maxcompute.aliyun.com", "47.116.XX.XX")
测试结果
说明
若您需要访问VPC网络的相关实例服务,请在VPC网络环境下,配置Python环境,替换实例服务所在VPC网络链接和IP地址进行测试。
-
在本地通过公网访问MaxCompute服务。
if __name__ == "__main__": access_url( url="https://service.cn-shanghai.maxcompute.aliyun.com", resolved_ip="47.116.XX.XX") "D:\Program Files\Python311\python.exe" D:\ProgramData\PycharmProjects\pythontest1\text.py success,resp : <!DOCTYPE html> <html> <head> <title>Welcome to tengine!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to tengine!</h1> <p>If you see this page, the tengine web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://tengine.taobao.org/">tengine.taobao.org</a>.</p> <p><em>Thank you for using tengine.</em></p> </body> </html> -
在Linux云服务器上通过公网访问MaxCompute服务。
[root@iZbp1ehm6ky76ig8n1jd8dZ opt]# python3 text.py success,resp : <!DOCTYPE html> <html> <head> <title>Welcome to tengine!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to tengine!</h1> <p>If you see this page, the tengine web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://tengine.taobao.org/">tengine.taobao.org</a>.</p> <p><em>Thank you for using tengine.</em></p> </body> </html>
该文章对您有帮助吗?