-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Websocket #755
Comments
Note, that tempesta/tempesta_fw/http_parser.c Line 1148 in c148f33
Other proxy servers require special directives in configuration file to allow passing |
Protocol upgrade request transforms connection into tunnel which doesn't use HTTP messages. So passing the request in the existing server connection will make it unusable and broken:
Currently protocol upgrade request will be forwarded to backend server without upgrade query. See comment above. Seems that a new server connection is required to serve the request (#710). The connection is not suitable to be used in schedulers. |
Many modern web sites use websockets, so severity is crucial |
For now i do no observe any dependency of the issue on |
Contributes to tempesta-tech#755 Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
Almost literaly follow ak patch from 2eae1da Replace GFSM calls with direct calls to TLS and HTTP handlers on low level networking layers. GFSM was designed to build graphs of network protocols FSMs (this design was inspired by FreeBSD netgraph). However, during the years neither we nor external users have any requirements to introduce any modules which use GFSM to hook TLS or HTTP entry code. There are only 2 users of the mechanism for TLS and HTTP for now: 1. TLS -> HTTP protocols handling 2. HTTP limits (the frang module) This patch replaces GFSM calls with direct calls to tfw_http_req_process(), tfw_tls_msg_process() and frang_tls_handler() in following paths: 1. sync sockets -> TLS 2. sync sockets -> HTTP 3. TLS -> HTTP 4. TLS -> Frang As the result the function tfw_connection_recv() was eliminated. Now the code is simpler and has lower overhead. We still might need GFSM for the user-space requests handling (tempesta-tech#77) and Tempesta Language (tempesta-tech#102). Contributes to tempesta-tech#755 Based-on-patch-by: Alexander K <ak@tempesta-tech.com> Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
Almost literaly follow ak patch from 2eae1da Replace GFSM calls with direct calls to TLS and HTTP handlers on low level networking layers. GFSM was designed to build graphs of network protocols FSMs (this design was inspired by FreeBSD netgraph). However, during the years neither we nor external users have any requirements to introduce any modules which use GFSM to hook TLS or HTTP entry code. There are only 2 users of the mechanism for TLS and HTTP for now: 1. TLS -> HTTP protocols handling 2. HTTP limits (the frang module) This patch replaces GFSM calls with direct calls to tfw_http_req_process(), tfw_tls_msg_process() and frang_tls_handler() in following paths: 1. sync sockets -> TLS 2. sync sockets -> HTTP 3. TLS -> HTTP 4. TLS -> Frang As the result the function tfw_connection_recv() was eliminated. Now the code is simpler and has lower overhead. We still might need GFSM for the user-space requests handling (tempesta-tech#77) and Tempesta Language (tempesta-tech#102). Contributes to tempesta-tech#755 Based-on-patch-by: Alexander K <ak@tempesta-tech.com> Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
Almost literaly follow ak patch from 2eae1da Replace GFSM calls with direct calls to TLS and HTTP handlers on low level networking layers. GFSM was designed to build graphs of network protocols FSMs (this design was inspired by FreeBSD netgraph). However, during the years neither we nor external users have any requirements to introduce any modules which use GFSM to hook TLS or HTTP entry code. There are only 2 users of the mechanism for TLS and HTTP for now: 1. TLS -> HTTP protocols handling 2. HTTP limits (the frang module) This patch replaces GFSM calls with direct calls to tfw_http_req_process(), tfw_tls_msg_process() and frang_tls_handler() in following paths: 1. sync sockets -> TLS 2. sync sockets -> HTTP 3. TLS -> HTTP 4. TLS -> Frang As the result the function tfw_connection_recv() was eliminated. Now the code is simpler and has lower overhead. We still might need GFSM for the user-space requests handling (tempesta-tech#77) and Tempesta Language (tempesta-tech#102). Contributes to tempesta-tech#755 Based-on-patch-by: Alexander K <ak@tempesta-tech.com> Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
Almost literaly follow ak patch from 2eae1da Replace GFSM calls with direct calls to TLS and HTTP handlers on low level networking layers. GFSM was designed to build graphs of network protocols FSMs (this design was inspired by FreeBSD netgraph). However, during the years neither we nor external users have any requirements to introduce any modules which use GFSM to hook TLS or HTTP entry code. There are only 2 users of the mechanism for TLS and HTTP for now: 1. TLS -> HTTP protocols handling 2. HTTP limits (the frang module) This patch replaces GFSM calls with direct calls to tfw_http_req_process(), tfw_tls_msg_process() and frang_tls_handler() in following paths: 1. sync sockets -> TLS 2. sync sockets -> HTTP 3. TLS -> HTTP 4. TLS -> Frang As the result the function tfw_connection_recv() was eliminated. Now the code is simpler and has lower overhead. We still might need GFSM for the user-space requests handling (tempesta-tech#77) and Tempesta Language (tempesta-tech#102). Contributes to tempesta-tech#755 Based-on-patch-by: Alexander K <ak@tempesta-tech.com> Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
Almost literaly follow ak patch from 2eae1da Replace GFSM calls with direct calls to TLS and HTTP handlers on low level networking layers. GFSM was designed to build graphs of network protocols FSMs (this design was inspired by FreeBSD netgraph). However, during the years neither we nor external users have any requirements to introduce any modules which use GFSM to hook TLS or HTTP entry code. There are only 2 users of the mechanism for TLS and HTTP for now: 1. TLS -> HTTP protocols handling 2. HTTP limits (the frang module) This patch replaces GFSM calls with direct calls to tfw_http_req_process(), tfw_tls_msg_process() and frang_tls_handler() in following paths: 1. sync sockets -> TLS 2. sync sockets -> HTTP 3. TLS -> HTTP 4. TLS -> Frang As the result the function tfw_connection_recv() was eliminated. Now the code is simpler and has lower overhead. We still might need GFSM for the user-space requests handling (tempesta-tech#77) and Tempesta Language (tempesta-tech#102). Contributes to tempesta-tech#755 Based-on-patch-by: Alexander K <ak@tempesta-tech.com> Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
Almost literaly follow ak patch from 2eae1da Replace GFSM calls with direct calls to TLS and HTTP handlers on low level networking layers. GFSM was designed to build graphs of network protocols FSMs (this design was inspired by FreeBSD netgraph). However, during the years neither we nor external users have any requirements to introduce any modules which use GFSM to hook TLS or HTTP entry code. There are only 2 users of the mechanism for TLS and HTTP for now: 1. TLS -> HTTP protocols handling 2. HTTP limits (the frang module) This patch replaces GFSM calls with direct calls to tfw_http_req_process(), tfw_tls_msg_process() and frang_tls_handler() in following paths: 1. sync sockets -> TLS 2. sync sockets -> HTTP 3. TLS -> HTTP 4. TLS -> Frang As the result the function tfw_connection_recv() was eliminated. Now the code is simpler and has lower overhead. We still might need GFSM for the user-space requests handling (#77) and Tempesta Language (#102). Contributes to #755 Based-on-patch-by: Alexander K <ak@tempesta-tech.com> Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
Contributes to tempesta-tech#755 Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
Contributes to #755 Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
Contributes to tempesta-tech#755 Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
Contributes to tempesta-tech#755 Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
Contributes to tempesta-tech#755 Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
Contributes to #755 Signed-off-by: Aleksey Mikhaylov <aym@tempesta-tech.com>
The backend can be tested with Node.js's |
It seems Webscokets over HTTP/2 aren't used:
Support of the feature in non-browser websocket implementations is crucial since we need automated tests for the feature. Otherwise we might find at some point that the feature was silently broken. #1625 is quite sophisticated and changes the logic of current HTTP messages management, so we might introduce additional bugs for the feature, which isn't used. |
Need to support Websocket (RFCs 6455), both the ws:// and wss:// schemes.
HTTP/1
Parser extensions
Upgrade: websocket
header RFC 7230 6.7 must be implemented. We support onlywebsocket
, so values likeh2c
orh2c, websocket
should be just ignored.Upgrade
directive forConnection
header. This must be done for requests (HTTP/1 and HTTP/2) and responses. It seems we shouldn't do anything if a server just advertisesUpgrade
w/o preceding clientUpgrade
request.Since
Upgrade
andConnection
is a hop by hop header, if we ignore their values, then a backend receives a request w/o the headers.If all the headers are good and we can upgrade to websocket, then a new websocket flag for the request must be set and
tfw_h1_adjust_req()
must regenerate the headers. Note thatSec-WebSocket-*
headers aren't hop-by-hop and shouldn't be stripped.All the extensions must be tested for HTTP/1 in
test_http_parser.c
Scheme parsing
Req_Uri
state at the moment handles onlyhttp://
scheme, which must be fixed to allowhttps://
and extend with the newws://
andwss://
. Since we'll need to match 4 strings, it makes sense to introduce new states with switch on prefixes (see as headers parsing is done). It seems that browsers never (or almost) never send full URLs, so the states should becold
andunlikely
.HTTP/2
Websockets for HTTP/2 are described in 8441 and we have a very special case of proxying HTTP/2 CONNECT to HTTP/1 websocket.
Nginx just proxies CONNECT method. I don't understand how reliable websockets in these setups, but there are issues in the Internet with websockets over HTTP/2 proxying by Nginx, e.g. RocketChat/Rocket.Chat#15028 . The problem is that RFC 8441 does not require an HTTP/2 client to set
Sec-WebSocket-Key
header, but maybe the most implementations actually do set the header.HAproxy implements the header computation for this case (see
h1_search_websocket_key()
). I believe we also should generate the header fromtfw_h2_adjust_req()
plus to generation ofUpgrade
andConnection
headers as intfw_h1_adjust_req()
.Parser extensions
:protocol
pseudo header and allowwebsocket
value only. It's not in the HPACK static table, but it seems we need to support it for the dynamic table compression from the client sideReq_HdrPsSchemeV
state withhttp
scheme forws
Please add the h2 tests to
t/unit/test_http_parser.c
.Backend connections
WebSockets must use separate TCP backend connection (i.e. a connection shall not be used to send send websocket frames from other client and/or HTTP messages from the same or other client). The same backend connection can be upgraded to websocket, meaning that a new TCP connection must be established (provisioned) with the backend to satisfy upcoming HTTP client requests. In this sense the issue depends/linked with #710 (dynamic server connections).
Once we receive 101 response from the server, we do
TfwConn->proto.type
to a new typesConn_WsClnt
andConn_WssClnt
and server's type toConn_WsSrv
andConn_WssSrv
, just like appropriate HTTP and HTTPS connectionswebsocket.[ch]
files.TfwConnHooks
for the connection to the appropriate websocket hooksSince we need to introduce a new connection type, it makes sense to port 2eae1da to not to bother with GFSM here.
Rate limits
Client and server inactivity timeouts as well as upgraded connection timeout must be configurable. Websocket server is a frequent target for DDoS attacks, so ratelimits for websocket client connections
client_ws_timeout
must be implemented. We can handle the server timeouts just as normal TCP timeouts.General considerations
Understanding the protocol
There is no need to decode or analyse WebSocket binary frames somehow, just pass them through. In future, probably we'll add some security checks, but not in the issue.
TCP proxying
It's recommended to use wss://, WebSocket over TLS, so we should just retransmit WebSocket application data messages after handshake. Because of TLS we can not use IPVS, and basically there is not much logic for IPVS.
Testing
The code probably can be tested by Node.js using the Websocket module. See Nginx's test as an example.
Functional tests for the issue are in #881, which depends on migration to Python3. If the migration isn't here in time, then just a simple Python3 scripts using the Python websockets must be developed. The scripts will later be used for #881.
References
Server-Sent Events, WebSockets, and HTTP by Mark Nottingham
The text was updated successfully, but these errors were encountered: