Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTPS request, specifying hostname and specific IP address

Tags:

node.js

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.

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.

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.

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?

I'm currently using node-fetch, but I'm happy to use whatever API is needed to make this work.

like image 790
Brad Avatar asked Nov 28 '18 15:11

Brad


People also ask

How is hostname used during HTTP request?

A host name is used when a web client makes an HTTP request to a host. The user making the request can specify the IP address of the server rather than the host name, but that is now unusual on the Internet. Host names are more convenient for users than numeric IP addresses.

Can you use curl with IP address?

To do this, we can use curl to query websites that are configured to do nothing more than return the IP address of whichever system is connecting to it. This is one of the quickest and easiest ways to get your public IP address on the Linux command line. Follow along with us below and we'll show you a few examples.

How do I resolve an IP address to a URL?

To do this in Chrome, simply open up the DevTools, navigate to the Network tab and select the site's HTML doc. You should then see the IP address associated with that URL under Headers > General > Remote Address.

How does curl resolve host name?

If no connection can be reused, libcurl resolves the host name to the set of addresses it resolves to. Typically this means asking for both IPv4 and IPv6 addresses and there may be a whole set of those returned to libcurl. That set of addresses is then tried until one works, or it returns failure.


1 Answers

Set the host header for the request:

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);
});

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'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'
}, ...)

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'
}, ...)

To keep things DRY, Node.js will set servername to the Host header, unless it's already set to something else (here).

like image 150
robertklep Avatar answered Oct 10 '22 04:10

robertklep