Skip to content
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

Refactor example-e2e test #19

Merged
merged 25 commits into from
Oct 7, 2022
Merged

Refactor example-e2e test #19

merged 25 commits into from
Oct 7, 2022

Conversation

M4tteoP
Copy link
Member

@M4tteoP M4tteoP commented Oct 3, 2022

Follows #12:

  • Merges the e2e and example logic providing a list of requests that can be both executed manually and run as e2e/inside the CI.
  • Adds some logic handling the response body intervention: response body is dropped if a deny action is triggered

@M4tteoP M4tteoP mentioned this pull request Oct 3, 2022
@M4tteoP M4tteoP changed the title Refactor e2e response body logic, response body logic Refactor e2en, response body logic Oct 3, 2022
@M4tteoP M4tteoP changed the title Refactor e2en, response body logic Refactor example-e2e test, response body logic Oct 3, 2022
@M4tteoP M4tteoP marked this pull request as draft October 3, 2022 12:46
README.md Outdated Show resolved Hide resolved
example/e2e-example.sh Outdated Show resolved Hide resolved
@@ -3,23 +3,26 @@ static_resources:
- address:
socket_address:
address: 0.0.0.0
port_value: 8001
port_value: 80
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

port 80 might not be the best choice for an example. One usually finds it occupied.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was mainly taking into account the usage of the example via docker-compose. In that case we will use ports 8080 and 8081 respectively for envoy and httpbin. Is it better to take into account also a standalone usage of the envoy config file?

filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: auto
http_protocol_options:
accept_http_10: true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we add a comment on why this is needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this option from the example and left a commit on the config for ftw.

main.go Outdated
if err != nil {
proxywasm.LogCriticalf("failed to perform interruption on response body: %v", err)
}
// TODO(M4tteop): I'm looking for the Go version of StopIterationNoBuffer
Copy link
Member Author

@M4tteoP M4tteoP Oct 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any advice about it? I don't feel calling SendHttpResponse twice is really a safe option even if it is working as I wish (close the connection even if the client is still waiting for the body).

Update in order to give a bit more context: the WAF has not detected any malicious pattern up to the response body, so, in order to avoid leakage, I just want to drop the connection and send back an empty body.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at https://github.com/proxy-wasm/proxy-wasm-cpp-sdk/blob/master/proxy_wasm_enums.h#L37-L42 and https://github.com/tetratelabs/proxy-wasm-go-sdk/blob/main/proxywasm/types/types.go#L22-L27 I guess there was a reason to not to mimic outputs and also an alternative to not to buffer the response body so maybe @mathetake can provide some context.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good q, I just wanted to simplify the API using the same status, rather than complex enums for each call back type (header, trailer, body/data, etc) as in C++.

I understand that you want to proactively drop the body, but in anyway the upcoming remaining body will be discarded immediately after the request fails, so do we REALLY want it?

main.go Outdated
proxywasm.LogCriticalf("failed to perform interruption on response body: %v", err)
}
// TODO(M4tteop): I'm looking for the Go version of StopIterationNoBuffer
// It is formally not correct to invoke SendHttpResponse during OnHttpResponseBody, but it is correctly closing the connection.
Copy link

@mathetake mathetake Oct 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does this mean? connection of what? what if it is http2?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what I wanted to say is that with the current impl of envoy, it's impossible to make the request fail after you return Continue in OnHttpResponseHeader proxy-wasm/proxy-wasm-cpp-host#143

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's the reason why we had the internal fork of cpp-host to change this behavior done by Takaya

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for confirming @mathetake. There are many proxy-wasm tasks we need to follow up on and finally have some budget for that so we'll try to make some progress there.

@M4tteoP In the meantime, it would be good to separate PRs for refactoring the example and response body logic. If you want to do the latter first, then my recommendation is to move ProcessResponseHeaders to OnHttpResponseBody). I can't find any coreruleset rules targeting response headers and this fits my intuition that there wouldn't be much to match there (maybe response cookies? But there isn't even a variable for that like there is for request cookies). There are a few response body rules though, so if we remove interruption in response headers we can still sanitize the response body when either interrupts there. What do you think?

main.go Outdated
Comment on lines 286 to 288
err = proxywasm.ReplaceHttpResponseBody([]byte(``))
if err != nil {
proxywasm.LogCriticalf("failed to perform interruption on response body: %v", err)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replacing with an empty buffer doesn't release anything in the host - it's just taking another string_view on the same memory region so this is just doing nothing.

Suggested change
err = proxywasm.ReplaceHttpResponseBody([]byte(``))
if err != nil {
proxywasm.LogCriticalf("failed to perform interruption on response body: %v", err)

@M4tteoP
Copy link
Member Author

M4tteoP commented Oct 4, 2022

The conversation about response body logic continues in #26

@M4tteoP
Copy link
Member Author

M4tteoP commented Oct 6, 2022

If it sounds good, I propose to merge this PR addressing only the refactor of the e2e, temporary commenting tests about the response body. They will be added again as soon as we agree on a short-term solution #26.

@M4tteoP M4tteoP marked this pull request as ready for review October 6, 2022 12:28
@M4tteoP M4tteoP changed the title Refactor example-e2e test, response body logic Refactor example-e2e test, ~~response body logic~~ Oct 6, 2022
@M4tteoP M4tteoP changed the title Refactor example-e2e test, ~~response body logic~~ Refactor example-e2e test Oct 6, 2022
e2e/Dockerfile Outdated Show resolved Hide resolved
e2e/Dockerfile Outdated Show resolved Hide resolved
e2e/Dockerfile Outdated Show resolved Hide resolved
volumes:
- logs:/home/envoy/logs:ro
tests:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you don't need this container for the example, the only reason this container is here, if I recall correctly is because you can curl the envoy directly from CI? If that is the case I recommend you create another docker-compose file in the e2e folder to include the script. See https://stackoverflow.com/questions/55650342/import-docker-compose-file-in-another-compose-file

On top of that, here I find a circular dependency: e2e depends on example and example depends on e2e (see https://github.com/corazawaf/coraza-proxy-wasm/pull/19/files#diff-fe02bc0074dfa40a0e1b60098921a60d187efae125046c3f008a5cdfa62cf028R60)

func E2e() error {
return sh.RunV("docker-compose", "--file", "e2e/docker-compose.yml", "up", "--abort-on-container-exit")
return sh.RunV("docker-compose", "-f", "e2e/docker-compose.yml", "up", "--abort-on-container-exit", "tests")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this rely on the example (example/docker-compose.yml) to be up and running already? If that is the case I'd recommend you bootstrap services on both files but in any case the command should not require you to do a previous command. See https://docs.docker.com/compose/extends/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option is of course to launch the example before the e2e

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mage e2e does not rely anymore on example/docker-compose.yml. I thought that a standalone and straightforward docker-compose was a cleaner alternative.
(Mainly had troubles with extends because of services with 'depends_on' cannot be extended).

@jcchavezs jcchavezs merged commit 6d0de78 into corazawaf:main Oct 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants