Closed kegsay closed 1 year ago
Write a module for mitmproxy exposing a DSL for easily modifying:
a. Requests flowing into the homeserver, simulating malicious or faulty clients. b. Responses flowing out of the homeserver, simulating malicious or faulty homeservers.
Place this in front of either Synapse, Dendrite or Conduit.
Pros:
Cons:
Additional cons for option E:
I ended up doing a blend of option C and D.
httputil
to implement a reverse proxy.The pros/cons end up being:
Pros:
Cons:
Additional cons for option E:
- It's python, so language context switch problems the same as with reverse proxy configuration files.
But you can write Python using Rust. Actually, people already do that https://github.com/mitmproxy/mitmproxy_rs.
Hmm, I do like the ability to have the web UI, and if it's a thing other people already use / have familiarity with then there is benefit to trying to make use of that.
In terms of configuration, these look to be equivalent (handrolled vs mitmproxy):
$ mitmdump --mode reverse:http://hs1@3000 --mode reverse:http://hs2@3001
$ REVERSE_PROXY_HOSTS=http://hs1,3000;http://hs2,3001 ./reverseproxy
Controlling what happens during the MITM process is the tricky bit I'm currently fleshing out. I want the API to look something like:
// stop /keys/query requests from working for alice, one time.
cancelInterception := tc.Deployment.ReverseProxyController.InterceptResponses(
t, rp.RespondWithError(504, "Gateway Timeout"),
rp.WithUserInfo(t, tc.Alice.BaseURL, tc.Alice.UserID, tc.Alice.DeviceID),
rp.WithPathSuffix("/keys/query"),
rp.WithRepititions(1),
)
defer cancelInterception()
so provided mitmproxy has the flexibility to do this then even if it is a custom DSL, it would be abstracted from the test. That way, those who do like mitmproxy can then make use of it.
So it sounds like I want a custom add-on, which seems to be able to manipulate the request/response e.g https://docs.mitmproxy.org/stable/addons-examples/#http-add-header
However, I need this to be modifiable at runtime so each test can tweak what things get set. This probably means I need to have a port exposed on the mitmproxy container to accept arbitrary(?) addons.
So it sounds like I want a custom add-on, which seems to be able to manipulate the request/response e.g https://docs.mitmproxy.org/stable/addons-examples/#http-add-header
Yes, you will most certainly want to write an extension, or multiple ones.
This probably means I need to have a port exposed on the mitmproxy container to accept arbitrary(?) addons.
Would it perhaps work if have a master addon/extension which then picks which extension to actually execute and having it listen on a UNIX socket so you can control this behavior?
That would compose pretty well if people then want to roll their own addons, it would just require the mitmproxy container to have all the addons preloaded in the image. It's also more secure than arbitrary code execution :D
Also gives a nice foundation for reimplementing the Polyjuice tests in a potentially more robust way, due to not requiring a fake homeserver reimplementation.
This now exists, but is missing contextual information to say "only do X for alice/device requests".
We can go a long way just with mimproxy filters so using that for now. Will expand this when needed. Proof of concept: https://github.com/matrix-org/complement-crypto/blob/main/tests/client_connectivity_test.go#L34
There are concrete test cases which require us to fudge connectivity to the server or fudge responses the server sends back. We cannot currently do this using complement-crypto, because we lack the necessary tooling. This issue tracks the addition of such tooling.
NB: This is different to mock federation servers which Complement natively supports well.
Option A: Mock Client Server
Extend mock federation server support in Complement to support mock client server support. This would allow us to mock up registration, message sending, etc.
Pros:
Cons:
Option B: Reverse Proxy MITM
Shove nginx/apache/traefik in front of the real HS, and write reverse proxy configuration to send back mocked responses, reject endpoints, etc.
Pros:
Cons:
Option C: Go reverse proxy MITM
Use Go's httputil package to write a reverse proxy in the test.
Pros:
Cons:
Option D: Transparent(ish) RPC
Use something like https://github.com/hashicorp/go-plugin/ to write a plugin which can then communicate over some kind of RPC channel that we don't care about.
Pros:
Cons: