检测 AWS 服务器是否在负载均衡器后面
Detect if AWS Server is behind a Load Balancer or not
目前同一网站 运行 在两个不同的服务器配置和两个不同的 URL 下。
- 位于负载平衡器后面的 IIS 服务器群
- 具有弹性 IP 的单个 IIS 服务器
为方便起见,最好在所有服务器上使用相同的代码 运行,因为这将简化部署过程。
我知道我可以做这样的事情:
if (string.Equals(HttpContext.Current.Request.Headers["X-Forwarded-Proto"], "https"))
这会检查负载均衡器是否转发了 'https' 数据。但是,我想做的只是检测负载均衡器是否存在。
要写的必备:if(LoadBalancerExists) { do this stuff }
有人知道怎么做吗?
事实证明,如果负载均衡器不存在Request.Headers["X-Forwarded-Proto"] == null
。
如果确实存在Request.Headers["X-Forwarded-Proto"] == 'http' or 'https'
快速解决方案:if(Request.Headers["X-Forwarded-Proto"] == null) { do stuff }
更新的解决方案增加了安全性,因为 headers 可以被欺骗:
ClientIP = Request.UserHostAddress;
Subnet = <enter your aws CIDR subnet address>; // e.g. 172.0.0.0
Mask = <enter your aws VPC address>; // e.g. 255.255.0.0
// Verify header
if(Request.Headers["X-Forwarded-Proto"] == null) {
// Verify that ClientIP i.e. the LoadBalancer's IP is inside of our subnet.
if(IsAddressOnSubnet(ClientAddress, Subnet, Mask)) {
// do some stuff
}
}
protected bool IsAddressOnSubnet(IPAddress Address, IPAddress Subnet, IPAddress Mask)
{
try
{
Byte[] addressOctets = Address.GetAddressBytes();
Byte[] subnetOctets = Mask.GetAddressBytes();
Byte[] networkOctets = Subnet.GetAddressBytes();
return
((networkOctets[0] & subnetOctets[0]) == (addressOctets[0] & subnetOctets[0])) &&
((networkOctets[1] & subnetOctets[1]) == (addressOctets[1] & subnetOctets[1])) &&
((networkOctets[2] & subnetOctets[2]) == (addressOctets[2] & subnetOctets[2])) &&
((networkOctets[3] & subnetOctets[3]) == (addressOctets[3] & subnetOctets[3]));
}
catch (System.Exception ex)
{
return false;
}
}
感谢 Michael-sqlbot 指出安全问题。
这个aws reference很有用。
检测ip地址在子网上的参考here感谢Спасибо! Прекрасное решение!.
目前同一网站 运行 在两个不同的服务器配置和两个不同的 URL 下。
- 位于负载平衡器后面的 IIS 服务器群
- 具有弹性 IP 的单个 IIS 服务器
为方便起见,最好在所有服务器上使用相同的代码 运行,因为这将简化部署过程。
我知道我可以做这样的事情:
if (string.Equals(HttpContext.Current.Request.Headers["X-Forwarded-Proto"], "https"))
这会检查负载均衡器是否转发了 'https' 数据。但是,我想做的只是检测负载均衡器是否存在。
要写的必备:if(LoadBalancerExists) { do this stuff }
有人知道怎么做吗?
事实证明,如果负载均衡器不存在Request.Headers["X-Forwarded-Proto"] == null
。
如果确实存在Request.Headers["X-Forwarded-Proto"] == 'http' or 'https'
快速解决方案:if(Request.Headers["X-Forwarded-Proto"] == null) { do stuff }
更新的解决方案增加了安全性,因为 headers 可以被欺骗:
ClientIP = Request.UserHostAddress;
Subnet = <enter your aws CIDR subnet address>; // e.g. 172.0.0.0
Mask = <enter your aws VPC address>; // e.g. 255.255.0.0
// Verify header
if(Request.Headers["X-Forwarded-Proto"] == null) {
// Verify that ClientIP i.e. the LoadBalancer's IP is inside of our subnet.
if(IsAddressOnSubnet(ClientAddress, Subnet, Mask)) {
// do some stuff
}
}
protected bool IsAddressOnSubnet(IPAddress Address, IPAddress Subnet, IPAddress Mask)
{
try
{
Byte[] addressOctets = Address.GetAddressBytes();
Byte[] subnetOctets = Mask.GetAddressBytes();
Byte[] networkOctets = Subnet.GetAddressBytes();
return
((networkOctets[0] & subnetOctets[0]) == (addressOctets[0] & subnetOctets[0])) &&
((networkOctets[1] & subnetOctets[1]) == (addressOctets[1] & subnetOctets[1])) &&
((networkOctets[2] & subnetOctets[2]) == (addressOctets[2] & subnetOctets[2])) &&
((networkOctets[3] & subnetOctets[3]) == (addressOctets[3] & subnetOctets[3]));
}
catch (System.Exception ex)
{
return false;
}
}
感谢 Michael-sqlbot 指出安全问题。
这个aws reference很有用。
检测ip地址在子网上的参考here感谢Спасибо! Прекрасное решение!.