loading...

How to Make curl Request a Site from a Different IP Than in DNS

peterc profile image Peter Cooper ・2 min read

One issue I've encountered over the years has been when moving a Web site between systems and the site is set up on two different servers simultaneously (this could also happen if using a CDN). Let's say example.com is set up on 1.1.1.1 and 2.2.2.2 but DNS is pointing solely to 1.1.1.1

What do we do if we want to request http://example.com/ but from 2.2.2.2?

A system wide approach would be adding an entry to the /etc/hosts file:

2.2.2.2 example.com
Enter fullscreen mode Exit fullscreen mode

This usually works but can require you to flush your local DNS cache and/or force refresh in your browser. You have to remember to remove the line as well, it's not very configurable, and so on.

What about if we want to use curl? You could use /etc/hosts but for debugging purposes it'd be nice if we could override the IP address on a single request basis as part of the command. This is possible!

The way I used to do it was to override the Host HTTP header (the way a HTTP client tells a server which host it's looking for) and request from the new IP address, like so:

curl -H "Host: example.com" http://2.2.2.2/
Enter fullscreen mode Exit fullscreen mode

Fine in the old days, but in the modern HTTPS world various problems are introduced. Luckily curl has a solution in the form of --resolve!

--resolve <host:port:address[,address]...>
       Provide a custom address for a  specific  host  and  port  pair.
       Using  this,  you  can make the curl requests(s) use a specified
       address and prevent the otherwise normally resolved  address  to
       be  used.
Enter fullscreen mode Exit fullscreen mode

So if we want to request example.com from 2.2.2.2, we could do this:

curl http://example.com/ --resolve example.com:80:2.2.2.2 
curl https://example.com/ --resolve example.com:443:2.2.2.2 
Enter fullscreen mode Exit fullscreen mode

Multiple entries can be added if needed for more complex situations like chains of redirects, say.

It's also possible to use * as a wildcard host so that any host involved in the request goes to the address you specify (and it could also save you a bit of redundancy and typing!):

curl http://example.com/ --resolve *:80:2.2.2.2
Enter fullscreen mode Exit fullscreen mode

Discussion

pic
Editor guide
Collapse
vaviloff profile image
Vaviloff

Wow, curl never ceases to amaze me, thanks for this awesome tip!