-
Notifications
You must be signed in to change notification settings - Fork 108
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
Better IP bind/listen flow #1123
Comments
Can you provide a little more insight on this one. Thanks |
Sure. It's a bit complex issue so feel free to ask more questions. mirrord hooks calls to bind/listen, so instead of actually binding/listening the given ports we randomize a port then pass the data to the agent so it can know what connections to steal/mirror for us. After writing this, I think maybe we should consider the IP specified in bind to be passed to the remote agent, but for it to work we need to also make sure that the local applications is able to obtain the remote's IPs to bind those. |
While investigating #1054 we've found out that When running the flask test, the server address stays as some
# first call to `getsockname`
stderr 2023-03-02T20:04:08.775908614Z 62732: 2023-03-02T20:04:08.775887Z DEBUG ThreadId(01) getsockname: mirrord_layer::socket::ops: getsockname -> local_address 127.0.0.1:33839 sockfd=10
(...)
# correct address
stderr 2023-03-02T20:04:08.787741559Z 62732: 2023-03-02T20:04:08.787718Z DEBUG ThreadId(01) getsockname: mirrord_layer::socket::ops: getsockname -> local_address 1.1.1.1:80 sockfd=11
(...)
# value from `request.server` should be `1.1.1.1`
stdout 2023-03-02T20:04:08.788315678Z 62732: ('127.0.0.1', 33839): Server value
stdout 2023-03-02T20:04:08.788342282Z 62732: HttpMethod.GET: Request completed |
Questions asked by @meowjesty on Discord:
|
The bind / listen restrictions should happen on layer only. There is no meaning to double binding a mirrored port for example. The objective is to not change/modify local app behavior and hide bugs (double bind for example) |
This means that on
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
bear-service NodePort 1.2.3.4 <none> 80:1234/TCP 1d
|
Yes. Exactly. struct Host {
remote_ip: SocketAddr,
local_ip: SocketAddr
}
Host{remote_ip: "1.2.3.4", local_ip: "1.1.1.1"} then when we do the actual bind we check if we want remote or local and use the appropriate? |
PR #1371 addresses only the double bind issue, but we still have an IP mismatch when the user I think the following steps would help to solve this:
I did something like this, but ended up with a different port when a message came through the TCP sniffer (don't know why yet). |
Not sure why we need that. |
You mean why we need this part?
We could save it as |
We're already returning the requested address: SocketState::Bound(bound) => Detour::Success(bound.requested_address.into()), if we want to get in the way somewhere, we need to change the way it decides what IPs are available for it. |
I think we achieved what we want for now :) |
while working on #1121 I found out that on my setup the listen fails because it binds each IP separately, leading to
ListenAlreadyExists
error and killing the layer.I am sending a PR that ignores this error, but we need in
bind
call to check if address is not already bound to preserve normal behavior (return error in that case instead of ignoring it)Edit:
We should hook all the functions that help resolve the local stack (ip, subnet, ports) so app want to listen on "localhost" it will then resolve to the real remote ip and will be able to bind on that ip, so
getsockname
would return also the remote ip even before accepting any connection.The text was updated successfully, but these errors were encountered: