Nginx configured as a reverse proxy can do this easily :
http {
upstream remoteserver {
# here you add your remote server's IPs or hostnames
server 54.175.222.246; # for example here we use HTTPBin's address
keepalive 10; # maintain a maximum of 10 open connections
}
server {
listen 80;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # passing the client's IP to the remote server, on a local machine it doesn't do much though
proxy_set_header Host $http_host; # passing the Host header as requested by the client, otherwise this will default to the pool's name, "remoteserver" in this case
proxy_pass http://remoteserver; # sends the request off to the pool defined above
}
}
}
Now you can point your scripts to the local server instead of the remote one, here's a demo with curl
:
$ curl http://localhost/get -H "Host: host header is passed normally"
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "host header is passed normally",
"User-Agent": "curl/7.29.0"
},
"origin": "127.0.0.1, 1.2.3.4",
"url": "http://host header is passed normally/get"
}
As you can see, even the Host header is passed as-is.
Or you can make the transition seamless by making the remote hostname point to your local machine, either in /etc/hosts
or in your DNS resolver's configuration. In this case, make sure to use only IP addresses instead of hostnames in the pool definition in Nginx's config, otherwise the proxy will also loop back to itself and that would cause a bit of a disaster.
Once the hosts file has been changed accordingly, the proxying is seamless :
$ curl http://httpbin.org/get -v
* About to connect() to httpbin.org port 80 (#0)
* Trying 127.0.0.1...
* Connected to httpbin.org (127.0.0.1) port 80 (#0)
> GET /get HTTP/1.1
> User-Agent: curl/7.29.0
> Host: httpbin.org
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.6.2
< Date: Sun, 15 Mar 2015 00:41:54 GMT
< Content-Type: application/json
< Content-Length: 198
< Connection: keep-alive
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
<
{
"args": {},
"headers": {
"Accept": "*/*",
"Host": "httpbin.org",
"User-Agent": "curl/7.29.0"
},
"origin": "127.0.0.1, 1.2.3.4",
"url": "http://httpbin.org/get"
}
As you can see, our local server behaves just like the remote one and any program attempting to access the remote hostname will actually connect to our local server.
Note that this may need additional configuration for HTTPS-based hosts.