使用共享 IP 地址从 IIS 站点发出出站 Web 请求时失败
outbound web requests fail when made from IIS sites using shared IP address
- IIS 7.5 / Windows 服务器 2008 R2
- 多个 IIS 站点使用主机名绑定到同一 IP 地址。
- 网站的入站流量工作正常。
- 后端站点代码发出的出站网络请求失败。远程站点 returns 404 (NotFound)。
- 已通过网络跟踪验证流量正在到达删除服务器。
- 如果从使用专用 IP 地址的站点(即不与任何其他站点共享)完成相同的请求,则可以正常工作。
任何人对如何使这项工作或可能出现的问题有任何想法?
托管服务器上的网络跟踪:
来自具有非共享 IP 地址的站点的成功请求:
No. Time Source Destination Protocol Info
6366 15:54:35.590463 192.168.1.76 173.194.77.121 HTTP GET /key/value/one/two HTTP/1.1
6369 15:54:35.599879 173.194.77.121 192.168.1.76 TCP http > 55407 [ACK] Seq=1 Ack=110 Win=344 Len=0
6370 15:54:35.621587 173.194.77.121 192.168.1.76 HTTP HTTP/1.1 200 OK (application/json)
6608 15:54:35.815774 192.168.1.76 173.194.77.121 TCP 55407 > http [ACK] Seq=110 Ack=357 Win=509 Len=0
使用共享 IP 地址的站点请求失败:
No. Time Source Destination Protocol Info
9720 15:54:39.244192 192.168.1.80 173.194.77.121 HTTP GET /key/value/one/two HTTP/1.1
9760 15:54:39.256958 173.194.77.121 192.168.1.80 TCP [TCP segment of a reassembled PDU]
9761 15:54:39.256962 173.194.77.121 192.168.1.80 HTTP HTTP/1.1 404 Not Found (text/html)
9762 15:54:39.257027 192.168.1.80 173.194.77.121 TCP 55438 > http [ACK] Seq=212 Ack=1676 Win=512 Len=0
代码:
public static HttpWebRequest CreateWebRequest(string url, string method = "GET", string referer = null, string contentType = null, int timeout = 100000, string authentication = null, string bindToIpAddress = null, string host = null)
{
var request = (HttpWebRequest)WebRequest.Create(url);
if (!string.IsNullOrWhiteSpace(bindToIpAddress))
{
IPAddress bindIp;
if (!IPAddress.TryParse(bindToIpAddress, out bindIp))
{
throw new ArgumentException("bindToIpAddress");
}
request.ServicePoint.BindIPEndPointDelegate = ((sp, rep, rc) =>
{
return new IPEndPoint(bindIp, 0);
});
}
request.Accept = "*/*";
request.ContentType = contentType;
request.Referer = referer;
request.Method = method;
request.Timeout = timeout;
if (!string.IsNullOrWhiteSpace(host))
{
request.Host = host;
}
return request;
}
string GetData()
{
try
{
string result;
var request = CreateWebRequest("http://jsonplaceholder.typicode.com/posts/1",
"GET",
"somedomain.com",
timeout: (10 * 1000),
bindToIpAddress: "192.168.27.133" /*site IP*/);
request.Accept = "application/json";
using (var response = request.GetResponse())
{
using (var sr = new StreamReader(response.GetResponseStream()))
{
result = sr.ReadToEnd();
}
}
return result;
}
catch (Exception ex)
{
return null;
}
}
404 响应从远程站点返回,因此远程站点无法处理您的请求,这与您本地服务器上发生的事情无关。
从远程站点的角度来看,唯一的区别是发件人的 IP 地址,因此必须将其配置为仅接受来自特定 IP 地址的请求。此限制可能在远程服务器或两者之间的任何防火墙、路由器或代理中。
这原来是我们应用程序中的一个错误。在某些情况下,主机 header(请求中的主机 属性)设置不正确(hosting/source 站点的主机名)。问题中精简的代码示例未显示。对于忽略 header 的 Web 服务来说很好,但对于其他 而不是 忽略 header 的服务来说是一个问题(404 响应)。该问题与 IIS 或共享 IP 地址无关。感谢大家的回复。
- IIS 7.5 / Windows 服务器 2008 R2
- 多个 IIS 站点使用主机名绑定到同一 IP 地址。
- 网站的入站流量工作正常。
- 后端站点代码发出的出站网络请求失败。远程站点 returns 404 (NotFound)。
- 已通过网络跟踪验证流量正在到达删除服务器。
- 如果从使用专用 IP 地址的站点(即不与任何其他站点共享)完成相同的请求,则可以正常工作。
任何人对如何使这项工作或可能出现的问题有任何想法?
托管服务器上的网络跟踪:
来自具有非共享 IP 地址的站点的成功请求:
No. Time Source Destination Protocol Info
6366 15:54:35.590463 192.168.1.76 173.194.77.121 HTTP GET /key/value/one/two HTTP/1.1
6369 15:54:35.599879 173.194.77.121 192.168.1.76 TCP http > 55407 [ACK] Seq=1 Ack=110 Win=344 Len=0
6370 15:54:35.621587 173.194.77.121 192.168.1.76 HTTP HTTP/1.1 200 OK (application/json)
6608 15:54:35.815774 192.168.1.76 173.194.77.121 TCP 55407 > http [ACK] Seq=110 Ack=357 Win=509 Len=0
使用共享 IP 地址的站点请求失败:
No. Time Source Destination Protocol Info
9720 15:54:39.244192 192.168.1.80 173.194.77.121 HTTP GET /key/value/one/two HTTP/1.1
9760 15:54:39.256958 173.194.77.121 192.168.1.80 TCP [TCP segment of a reassembled PDU]
9761 15:54:39.256962 173.194.77.121 192.168.1.80 HTTP HTTP/1.1 404 Not Found (text/html)
9762 15:54:39.257027 192.168.1.80 173.194.77.121 TCP 55438 > http [ACK] Seq=212 Ack=1676 Win=512 Len=0
代码:
public static HttpWebRequest CreateWebRequest(string url, string method = "GET", string referer = null, string contentType = null, int timeout = 100000, string authentication = null, string bindToIpAddress = null, string host = null)
{
var request = (HttpWebRequest)WebRequest.Create(url);
if (!string.IsNullOrWhiteSpace(bindToIpAddress))
{
IPAddress bindIp;
if (!IPAddress.TryParse(bindToIpAddress, out bindIp))
{
throw new ArgumentException("bindToIpAddress");
}
request.ServicePoint.BindIPEndPointDelegate = ((sp, rep, rc) =>
{
return new IPEndPoint(bindIp, 0);
});
}
request.Accept = "*/*";
request.ContentType = contentType;
request.Referer = referer;
request.Method = method;
request.Timeout = timeout;
if (!string.IsNullOrWhiteSpace(host))
{
request.Host = host;
}
return request;
}
string GetData()
{
try
{
string result;
var request = CreateWebRequest("http://jsonplaceholder.typicode.com/posts/1",
"GET",
"somedomain.com",
timeout: (10 * 1000),
bindToIpAddress: "192.168.27.133" /*site IP*/);
request.Accept = "application/json";
using (var response = request.GetResponse())
{
using (var sr = new StreamReader(response.GetResponseStream()))
{
result = sr.ReadToEnd();
}
}
return result;
}
catch (Exception ex)
{
return null;
}
}
404 响应从远程站点返回,因此远程站点无法处理您的请求,这与您本地服务器上发生的事情无关。
从远程站点的角度来看,唯一的区别是发件人的 IP 地址,因此必须将其配置为仅接受来自特定 IP 地址的请求。此限制可能在远程服务器或两者之间的任何防火墙、路由器或代理中。
这原来是我们应用程序中的一个错误。在某些情况下,主机 header(请求中的主机 属性)设置不正确(hosting/source 站点的主机名)。问题中精简的代码示例未显示。对于忽略 header 的 Web 服务来说很好,但对于其他 而不是 忽略 header 的服务来说是一个问题(404 响应)。该问题与 IIS 或共享 IP 地址无关。感谢大家的回复。