Layanan remote di dalam VPC hanya mendukung akses melalui nama domain. Permintaan yang dilakukan langsung menggunakan alamat IP akan gagal. Topik ini menjelaskan cara mengakses layanan HTTPS melalui alamat IP dengan menambahkan nama domain ke Header Host pada permintaan. Metode ini berguna dalam skenario akses remote, seperti tugas Spark atau User-Defined Function (UDF).
Kegagalan akses HTTPS melalui alamat IP
Pesan error
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.
Deskripsi masalah
Saat tugas Spark atau UDF menggunakan alamat IP untuk mengakses layanan remote seperti KMS atau OSS melalui HTTPS di dalam VPC, permintaan gagal dengan error yang ditunjukkan di atas.
Solusi
Untuk mengatasi kegagalan validasi sertifikat SSL yang terjadi saat menggunakan alamat IP untuk mengakses layanan HTTPS, tambahkan nama domain layanan tersebut ke Header Host permintaan.
1. Dapatkan alamat IP layanan remote.
Gunakan ping
Dari konsol Windows atau Linux, jalankan perintah berikut untuk mendapatkan alamat IP layanan remote.
ping service.cn-shanghai-vpc.maxcompute.aliyun-inc.com
-
Hasil 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 -
Hasil 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.
Gunakan dig
-
Instal bind-utils di lingkungan Windows atau Linux Anda.
-
Windows
Unduh BIND9.17.12.x64.zip, ekstrak ke direktori seperti
D:\install\BIND9.17.12.x64, lalu tambahkan path ini ke variabel lingkungan Path di Windows. -
Linux (CentOS)
Jalankan
sudo yum install bind-utilsuntuk menginstal paket tersebut.
-
-
Jalankan perintah berikut di konsol Anda:
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. Konfigurasikan client HTTP.
Contoh kode berikut menunjukkan cara membuat adapter HTTP kustom untuk versi Python yang berbeda. Adapter ini mengirim alamat IP dalam URL permintaan tetapi menggunakan nama domain asli dalam Header Host untuk validasi SSL. Sebelum menerbitkan tugas Anda, uji akses remote dari lingkungan jaringan yang sesuai.
-
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 hostname 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("Error: "+ str(e)) else: if r.status_code != 200: print("Request failed with non-200 status. Response: "+ r.text) else: print("Success. Response: "+ r.text) if __name__ == "__main__": # Obtain the IP address by using 'dig' for the domain name within the VPC environment. # Test a VPC address. #access_url("https://service.cn-shanghai-vpc.maxcompute.aliyun-inc.com", "100.103.104.45") # Test a public network address. 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: # Clear headers that might be left from a previous request. connection_pool_kwargs.pop('server_hostname', None) return super().send(request, **kwargs) def access_url(url, resolved_ip): session = requests.Session() # Get the hostname 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("Error: "+ str(e)) else: if r.status_code != 200: print("Request failed with non-200 status. Response: "+ r.text) else: print("Success. Response: "+ r.text) if __name__ == "__main__": # Obtain the IP address by using 'dig' for the domain name within the VPC environment. # Test a VPC address. #access_url("https://service.cn-shanghai-vpc.maxcompute.aliyun-inc.com", "100.103.104.45") # Test a public network address. access_url("https://service.cn-shanghai.maxcompute.aliyun.com", "47.116.XX.XX")
Hasil pengujian
Jalankan pengujian dari lingkungan jaringan yang sama dengan tugas Anda. Untuk mengakses layanan di dalam VPC, siapkan lingkungan Python di dalam VPC tersebut dan gunakan URL layanan serta alamat IP yang diperoleh dari dalam VPC itu.
-
Akses layanan MaxCompute dari mesin lokal melalui jaringan publik.
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. Response: <!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>Thank you for using tengine.</p> </body> </html> -
Akses layanan MaxCompute dari instance ECS Linux melalui jaringan publik.
[root@iZbp1ehm6ky76ig8n1jd8dZ opt]# python3 text.py Success. Response: <!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>Thank you for using tengine.</p> </body> </html>