HTTPS请求,指定主机名和特定的IP地址
我为我的应用程序服务器使用了基于Node.js的部署脚本.部署过程中的第一步是在向DNS注册之前,验证这些应用服务器是否正确侦听HTTPS.为此,我只需要向该服务器的IP地址发出HTTPS请求即可.
I have a Node.js-based deployment script for my application servers. One step in the deployment process is to validate that these application servers are listening on HTTPS correctly before registering them with DNS. To do that, I simply need to make an HTTPS request to that server's IP address.
如果这是HTTP,则不是问题.我可以对http://[2001:0db8::0370:7334]/
发出HTTP GET
请求,这将起作用.但是,如果我对https://[2001:0db8::0370:7334]/
发出HTTPS GET请求,则该操作将失败,因为该证书用于特定的主机名,例如api.example.com
.
If this were HTTP, it's a non-issue. I can make a HTTP GET
request for http://[2001:0db8::0370:7334]/
, and this will work. However, if I make an HTTPS GET request for https://[2001:0db8::0370:7334]/
, this will fail since the certificate is for a specific hostname like api.example.com
.
如果我正在手动测试,我会暂时将IP地址放在hosts
文件和cURL https://api.example.com
中.但是,在此自动化过程中,我可能一次部署多个主机,因此这不是我的部署脚本的解决方案.
If I were testing manually, I would temporarily put the IP address in the hosts
file and cURL https://api.example.com
. However, in this automated process, I may be deploying several hosts at once so this isn't a solution for my deployment script.
如何在指定主机名和IP地址的地方发出HTTPS请求?
How can I make an HTTPS request where I specify the hostname and IP address?
也许有某种方法可以通过自定义代理进行操作?
Perhaps there's some way to do this with a custom Agent?
我目前正在使用 node-fetch ,但我很乐意使用进行此工作所需的任何API.
I'm currently using node-fetch, but I'm happy to use whatever API is needed to make this work.
设置请求的host
标头:
const https = require('https');
https.get('https://AA.BB.CC.DD', {
headers : { host : 'api.example.com' }
}, res => {
console.log('okay');
}).on('error', e => {
console.log('E', e.message);
});
编辑:我仔细研究了一下它是如何工作的.为了允许基于HTTPS的虚拟主机,有一个名为 SNI(服务器名称指示)的TLS扩展.客户端使用此扩展名来指示其尝试连接的主机名,以便服务器可以选择属于该主机名的适当证书.
EDIT: I dug around a bit to see how this works exactly. To allow HTTPS-based virtual hosting, there's a TLS extension called SNI (Server Name Indication). This extension is used by a client to indicate the hostname to which it is trying to connect, so the server can pick the appropriate certificate that belongs to that hostname.
Node的tls
模块具有选项 servername
设置此主机名:
Node's tls
module, which is used by https
, has an option servername
to set this hostname:
https.get('https://AA.BB.CC.DD', {
servername : api.example.com'
}, ...)
但是,您仍然还需要传递Host
标头(这是常规HTTP协议的一部分):
However, you still need to pass a Host
header too (that's part of the regular HTTP protocol):
https.get('https://AA.BB.CC.DD', {
headers : { host : 'api.example.com' },
servername : 'api.example.com'
}, ...)
为使内容保持干燥,Node.js会将servername
设置为Host
标头,除非已将其设置为其他内容(
To keep things DRY, Node.js will set servername
to the Host
header, unless it's already set to something else (here).