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

Ability to extend Apache server with Wasm modules #59

Open
gzurl opened this issue Jul 24, 2023 · 0 comments
Open

Ability to extend Apache server with Wasm modules #59

gzurl opened this issue Jul 24, 2023 · 0 comments
Labels
🚀 enhancement New feature or request 🛟 help wanted Extra attention is needed

Comments

@gzurl
Copy link
Contributor

gzurl commented Jul 24, 2023

Is your feature request related to a problem? Please describe.

Apache server's extension mechanism works through modules written in C:

Some modules, such as mod_lua or mod_perl, try to relax this requirement by exposing Apache's internal APIs to different programming languages.

We aim to expand these capabilities by allowing the possibility of rewriting any existing Apache module in any programming language that can target WebAssembly (ie: Rust, Go, etc.) or even interpreted languages (ie: Python, PHP, Ruby, etc.).

Describe the solution you'd like

The initial version of mod_wasm was created with the purpose of serving content from WebAssembly binaries, enabling the execution of traditional applications within a Wasm-based stack (ie: WordPress, Drupal, etc.).

This extensibility through mod_wasm requires Wasm modules to gain access to Apache’s internal API through host functions, as well as a mechanism to hook into the different HTTP request stages. We don’t need to expose the entire Apache’s API; a core subset may be enough (ie: exposed data structures and built-in functions in mod_lua).

By compiling these new modules to WebAssembly, they can effectively work as traditional Apache modules for activities such as monitoring, modifying headers, filtering requests, security, etc. all while benefiting from the safety provided by the Wasm sandboxing model and being coded in your preferred programming language. More importantly, a programming bug in a module (ie: segfault) won’t crash the entire Apache server as currently happens when the module is natively compiled into a .so library.

Describe alternatives you've considered

Exposing the entire Apache API to mod_wasm would require a significant effort. Instead, it would be more practical to select a subset that can provide new features. Examples include reading and modifying headers, registering hooks, and supporting the proxy-wasm specification. Then, encourage the community to keep implementing the remaining APIs for other use cases.

Regarding the Apache API, @assambar submitted a PoC (PR#55) demonstrating how to manage headers from a Wasm module. In addition, @gzurl submitted another PoC (PR#57) to showcase how Wasm exported functions can be automatically registered into Apache’s hooks without any extra boilerplate code. By combining and integrating these two PoCs in a robust manner and extending the exposed Apache APIs, we can develop a new mod_wasm version where Wasm modules can replace certain functionality from the traditional Apache modules.

Additional context

We propose three iterations to achieve this goal:

Iteration 0: Define new directives and configuration features:

  • New Apache directives will be needed to distinguish the kind of Wasm modules to run (content handler or extension) and the group of host functions to enable (ie: WasmModule, WasmApacheModule, …)
  • Also, existing Wasm directives (ie: WasmDir, WasmEnv, …) will need to be applied to different Wasm module types.
  • This iteration is also a good opportunity to refactor the current code to make room for the upcoming features. Also, invest some time in missing CI common stuff that will be certainly needed in future iterations (E2E “Hello, Wasm!” test (Add minimal E2E testing #11), automate releases, etc).

Iteration 1: Implement new directives, self-registered hooks and expose request_recstructure:

  • HTTP requests' data will be passed to the new Apache Wasm modules in read-only mode (actually, not providing manipulation functions). This enables use cases such as simple firewall-like functionality.
  • In this iteration, we will need to create an apache_bindings.rs Rust module (or crate) to access the Apache API’s data structures (ie: request_rec, etc.). This will probably be the seed of the apache-wasm-rust-sdk. We should try hard to use bindgen for exposing C structures into Rust instead of manual migration. We will appreciate that later.
  • Also, during this iteration, we can start dealing with a quick and efficient manner to access the headers and body without copying strings back and forth.

Iteration 2: Add support for host functions and expose basic Apache APIs

  • This iteration is about evolving from read-only to read-write operations, where specific host functions wrapping the Apache API will be required.
  • New exposed Apache APIs come from simple ap_log_*, to more complex apr_table_* functions, enabling request and response manipulation.
  • At this point, we should be showcasing a similar (but limited) functionality to other modules like mod_lua or mod_tcl. And offering the capability to reimplement modules like mod_headers or even mod_rewrite.
@gzurl gzurl added 🚀 enhancement New feature or request 🛟 help wanted Extra attention is needed labels Jul 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🚀 enhancement New feature or request 🛟 help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

1 participant