我有一个使用反向代理的HTTP加速解决方案。为了向服务器提供客户端IP,我试图在我的HTTP加速解决方案中添加代理协议支持。虽然由于HTTP Acceleration解决方案端点本身不能作为我的服务器的网关,但我需要在服务器中添加代理协议支持或在它们前面添加HA代理。
目前用于代理协议状态:
接收器可以配置为支持协议的版本1和版本2。识别协议版本很简单:
- if the incoming byte count is 16 or above and the 13 first bytes match
the protocol signature block followed by the protocol version 2 :
\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A\x02
- otherwise, if the incoming byte count is 8 or above, and the 5 first
characters match the US-ASCII representation of "PROXY" then the protocol
must be parsed as version 1 :
\x50\x52\x4F\x58\x59
- otherwise the protocol is not covered by this specification and the
connection must be dropped.
我的服务器主要是 nginx ,它支持代理协议。虽然我的http服务器很少支持代理协议
我的问题是服务器是否不支持该协议,是否可以正确解析包含代理协议头的TCP / HTTP有效负载?
在同一个说明中,我想知道为什么代理协议规范没有将其作为 TCP / Ip标头选项: 通过这种方式,不理解该选项的服务器将忽略使其完全透明到不支持它的服务器。 那些支持该协议的服务器将丢弃没有代理协议选项的数据包
答案 0 :(得分:1)
我的问题是服务器是否不支持该协议,是否可以正确解析包含代理协议头的TCP / HTTP有效负载?
不,不支持代理协议的服务器将无法将请求解析为HTTP,因为它不以有效的HTTP方法开头。
简单地省略不支持代理协议的后端服务器的send-proxy
指令。请注意,除非您在X-Forwarded-For
标题中传递信息,否则您将丢失有关客户的信息。
答案 1 :(得分:1)
以下是代理协议信息的示例:
如果服务器不支持该协议,是否可以正确解析包含代理协议头的TCP / HTTP有效负载?
这取决于服务器实施。
例如,我尝试将代理协议信息发送到python的HTTPServer,它抛出了400错误代码。以下是解析标题的服务器的实现:
def parse_request(self):
"""Parse a request (internal).
The request should be stored in self.raw_requestline; the results
are in self.command, self.path, self.request_version and
self.headers.
Return True for success, False for failure; on failure, an
error is sent back.
"""
self.command = None # set in case of error on the first line
self.request_version = version = self.default_request_version
self.close_connection = 1
requestline = self.raw_requestline
requestline = requestline.rstrip('\r\n')
self.requestline = requestline
words = requestline.split()
if len(words) == 3:
command, path, version = words
if version[:5] != 'HTTP/':
self.send_error(400, "Bad request version (%r)" % version)
return False
try:
base_version_number = version.split('/', 1)[1]
version_number = base_version_number.split(".")
# RFC 2145 section 3.1 says there can be only one "." and
# - major and minor numbers MUST be treated as
# separate integers;
# - HTTP/2.4 is a lower version than HTTP/2.13, which in
# turn is lower than HTTP/12.3;
# - Leading zeros MUST be ignored by recipients.
if len(version_number) != 2:
raise ValueError
version_number = int(version_number[0]), int(version_number[1])
except (ValueError, IndexError):
self.send_error(400, "Bad request version (%r)" % version)
return False
if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1":
self.close_connection = 0
if version_number >= (2, 0):
self.send_error(505,
"Invalid HTTP Version (%s)" % base_version_number)
return False
elif len(words) == 2:
command, path = words
self.close_connection = 1
if command != 'GET':
self.send_error(400,
"Bad HTTP/0.9 request type (%r)" % command)
return False
elif not words:
return False
else:
self.send_error(400, "Bad request syntax (%r)" % requestline)
return False
self.command, self.path, self.request_version = command, path, version
# Examine the headers and look for a Connection directive
self.headers = self.MessageClass(self.rfile, 0)
conntype = self.headers.get('Connection', "")
if conntype.lower() == 'close':
self.close_connection = 1
elif (conntype.lower() == 'keep-alive' and
self.protocol_version >= "HTTP/1.1"):
self.close_connection = 0
return True
请注意代理协议有效负载,例如:
PROXY TCP4 192.168.73.178 192.168.73.185 52406 80
包含6个字。如果标头有3,2或没有单词,则此特定服务器实现处理reqeust。否则会抛出400错误代码。
else:
self.send_error(400, "Bad request syntax (%r)" % requestline)
return False
当我尝试将相同的信息发送到具有相同HAProxy配置的tomcat服务器时,它只是忽略了有效负载。
一般情况下,除非我知道明确能够处理代理信息,否则我会安全地播放代理信息。