π¦ Rama (γ©γ) is a modular service framework for the π¦ Rust language to move and transform your network packets. The reasons behind the creation of rama can be read in the "Why Rama" chapter.
Rama is async-first using Tokio as its only Async Runtime.
Please refer to the examples found in the /examples
dir
to get inspired on how you can use it for your purposes.
π‘ If your organization relies on Rama (γ©γ) for its operations, we invite you to consider becoming a sponsor π. By supporting our project, you'll help ensure its continued development and success. To learn more about sponsorship opportunities, please refer to the "Sponsors" section below or contact us directly at [email protected].
This framework comes with π batteries included, giving you the full freedome to build the middleware and services you want, without having to repeat the "common":
category | support list |
---|---|
β transports | β tcp βΈ± ποΈ udp (2) βΈ± β middleware |
β http | β auto βΈ± β http/1.1 βΈ± β h2 βΈ± ποΈ h3 (2) βΈ± β middleware |
β web server | β fs βΈ± β redirect βΈ± β dyn router βΈ± β static router βΈ± β handler extractors βΈ± β k8s healthcheck |
β http client | β client βΈ± β high level API βΈ± β Proxy Connect βΈ± β Chromium Http (3) |
β tls | β Rustls βΈ± β BoringSSL βΈ± β NSS (3) |
β dns | β DNS Resolver |
β proxy protocols | β PROXY protocol βΈ± β http proxy βΈ± β https proxy βΈ± ποΈ SOCKS5 (1) βΈ± ποΈ SOCKS5H (1) |
ποΈ web protocols | ποΈ Web Sockets (WS) (2) βΈ± ποΈ WSS (2) βΈ± β Web Transport (3) βΈ± β gRPC (3) |
β async-method trait services | β Service βΈ± β Layer βΈ± β context βΈ± β dyn dispatch βΈ± β middleware |
β telemetry | β tracing βΈ± β opentelemetry βΈ± β http metrics βΈ± β transport metrics |
β upstream proxies | β MemoryProxyDB βΈ± β L4 Username Config βΈ± β Proxy Filters |
ποΈ User Agent (UA) | ποΈ Http Emulation (1) βΈ± ποΈ Tls Emulation (1) βΈ± β UA Parsing |
β utilities | β error handling βΈ± β graceful shutdown βΈ± ποΈ Connection Pool (2) βΈ± ποΈ IP2Loc (2) |
ποΈ TUI | ποΈ traffic logger (2) βΈ± ποΈ curl export (2) βΈ± β traffic intercept (3) βΈ± β traffic replay (3) |
β binary | β prebuilt binaries βΈ± ποΈ proxy config (2) βΈ± β http client βΈ± β WASM Plugins (3) |
ποΈ data scraping | ποΈ Html Processor (2) βΈ± β Json Processor (3) |
β browser | β JS Engine (3) βΈ± β Web API Emulation (3) |
ποΈ Footnotes
- (1) Part of
v0.2.0
milestone (ETA: 2024 mid Q3)- (2) Part of
v0.3.0
milestone (ETA: 2024 end Q3)- (3) No immediate plans, but on our radar. Please open an issue to request this feature if you have an immediate need for it. Please add sufficient motivation/reasoning and consider becoming a sponsor to help accelerate its priority.
The primary focus of Rama is to aid you in your development of proxies:
- π¦ Reverse proxies;
- π TLS Termination proxies;
- π HTTP(S) proxies;
- 𧦠SOCKS5 proxies (will be implemented in
v0.3
); - π MITM proxies;
- π΅οΈββοΈ Distortion proxies.
π‘ Check out the "Intro to Proxies" chapters in the Rama book to learn more about the different kind of proxies. It might help in case you are new to developing proxies.
The Distortion proxies support
comes with User Agent (UA) emulation capabilities. The emulations are made possible by patterns
and data extracted using rama-fp
. The service is publicly exposed at
https://fp.ramaproxy.org, made possible by our sponsor host https://fly.io/.
π https://echo.ramaproxy.org/ is another service publicly exposed. In contrast to the Fingerprinting Service it is aimed at developers and allows you to send any http request you wish in order to get an insight on the Tls Info and Http Request Info the server receives from you when making that request.
curl -XPOST 'https://echo.ramaproxy.org/foo?bar=baz' \ -H 'x-magic: 42' --data 'whatever forever'Feel free to make use of while crafting distorted http requests, but please do so with moderation. In case you have ideas on how to improve the service, please let us know by opening an issue.
Using the
rama
binary you can also run both theecho
andfp
service yourself, locally or as an external facing web service.Please run your own echo service instead of using
echo.ramaproxy.org
in case you are planning to send a lot of traffic to the echo service.
BrowserStack sponsors Rama by providing automated cross-platform browser testing on real devices, which uses the public fingerprinting service to aid in automated fingerprint collection on both the Http and Tls layers. By design we do not consider Tcp and Udp fingerprinting.
Next to proxies, Rama can also be used to develop Web Services and Http Clients.
- Learn more by reading the Rama book at https://ramaproxy.org/book;
- or checkout the framework Rust docs at https://docs.rs/rama;
- edge docs (for main branch) can be found at https://ramaproxy.org/docs/rama.
π Rama's full documentation, references and background material can be found in the form of the "rama book" at https://ramaproxy.org/book.
π¬ Come join us at Discord on the #rama
public channel. To ask questions, discuss ideas and ask how rama may be useful for you.
The rama
binary allows you to use a lot of what rama
has to offer without
having to code yourself. It comes with a working http client for CLI, which emulates
User-Agents and has other utilities. And it also comes with IP/Echo services.
It also allows you to run a rama
proxy, configured to your needs.
Learn more about the rama
binary and how to install it at https://ramaproxy.org/book/binary/rama.
π¦ Rama (γ©γ) is to be considered experimental software for the foreseeable future. In the meanwhile it is already used
in production by ourselves and others alike. This is great as it gives us new perspectives and data to further improve
and grow the framework. It does mean however that there are still several non-backward compatible releases that will follow 0.2
.
In the meanwhile the async ecosystem of Rust is also maturing, and edition 2024 is also to be expected as a 2024 end of year gift. It goes also without saying that we do not nilly-willy change designs or break on purpose. The core design is by now also well defined. But truth has to be said, there is still plenty to be improve and work out. Production use and feedback from you and other users helps a lot with that. As such, if you use Rama do let us know feedback over Discord, email or a GitHub issue.
π If you are a company or enterprise that makes use of Rama, or even an individual user that makes use of Rama for commcercial purposes. Please consider becoming a business/enterprise subscriber. It helps make the development cycle to remain sustainable, and is beneficial to you as well. As part of your benefits we are also available to assist you with migrations between breaking releases. For enterprise users we can even make time to develop those PR's in your integration codebases ourselves on your behalf. A win for everybody. πͺ
For now there are only the rama crates found in this repository, also referred to as "official" rama crates.
We welcome however community contributions not only in the form of contributions to this repository, but also have people write their own crates as extensions to the rama ecosystem. E.g. perhaps you wish to support an alternative http/tls backend.
In case you have ideas for new features or stacks please let us know first. Perhaps there is room for these within an official rama crate. In case it is considered out of scope you are free to make your own community rama crate. Please prefix all rama community crates with "rama-x", this way the crates are easy to find, and are sufficiently different from "official" rama crates".
Once you have such a crate published do let us know it, such that we can list them here.
The rama
crate can be used as the one and only dependency.
However, as you can also read in the "DIY" chapter of the book
at https://ramaproxy.org/book/diy.html#empowering, you are able
to pick and choose not only what specific parts of rama
you wish to use,
but also in fact what specific (sub) crates.
Here is a list of all rama
crates:
rama
: one crate to rule them allrama-error
: error utilities for rama and its usersrama-macros
: contains the procedural macros used byrama
rama-utils
: utilities crate for ramarama-core
: core crate containing the service, layer and context used by all otherrama
code, as well as some other core utilitiesrama-net
: rama network types and utilitiesrama-dns
: DNS support for ramarama-tcp
: TCP support for ramarama-udp
: UDP support for ramarama-tls
: TLS support for rama (types,rustls
andboring
)rama-proxy
: proxy types and utilities for ramarama-socks5
: SOCKS5 support for ramarama-haproxy
: rama HaProxy supportrama-ua
: User-Agent (UA) support forrama
rama-http-types
: http types and utilitiesrama-http
: rama http services, layers and utilitiesrama-http-backend
: default http backend forrama
rama-http-core
: http protocol implementation drivingrama-http-backend
- /examples/tls_termination.rs: Spawns a mini handmade http server, as well as a TLS termination proxy, forwarding the plain text stream to the first.
- /examples/tls_termination.rs: Spawns a mini handmade http server, as well as a TLS termination proxy, forwarding the plain text stream to the first.
- /examples/mtls_tunnel_and_service.rs: Example of how to do mTls (manual Tls, where the client also needs a certificate) using rama, as well as how one might use this concept to provide a tunnel service build with these concepts;
- /examples/http_connect_proxy.rs: Spawns a minimal http proxy which accepts http/1.1 and h2 connections alike, and proxies them to the target host.
Developing proxies are the primary focus of Rama (γ©γ). It can however also be used to develop web services to serve web pages, Http API's and static content. This comes with many of the same benefits that you get when developing proxies using Rama:
- Use Async Method Traits;
- Reuse modular Tower-like middleware using extensions as well as strongly typed state;
- Have the ability to be in full control of your web stack from Transport Layer (Tcp, Udp), through Tls and Http;
- If all you care about is the Http layer then that is fine to.
- Be able to trust that your incoming Application Http data has not been modified (e.g. Http header casing and order is preserved);
- Easily develop your service at a Request layer and High level functions alike, choices are yours and can be combined.
Examples of the kind of web services you might build with rama in function of your proxy service:
- a k8s health service (/examples/http_k8s_health.rs);
- a metric exposure service;
- a minimal api service (e.g. to expose device profiles or certificates);
- a graphical interface / control panel;
π Learn more about developing web services in the Rama book: https://ramaproxy.org/book/web_servers.html.
Here are some low level web service examples without fancy features:
- /examples/http_listener_hello.rs: is the most basic example on how to provide
a root service with no needs for endpoints or anything else (e.g. good enough for some use cases related
to health services or metrics exposures);
- /examples/http_health_check.rs is an even more minimal example of a health check service returning a 200 OK for any incoming request.
- /examples/http_service_hello.rs: is an example similar to the previous example but shows how you can also operate on the underlying transport (TCP) layer, prior to passing it to your http service;
There's also a premade webservice that can be used as the health service for your proxy k8s workloads:
- /examples/http_k8s_health.rs: built-in web service that can be used as a k8s health service for proxies deploying as a k8s deployment;
The following are examples that use the high level concepts of Request/State extractors and IntoResponse converters,
that you'll recognise from axum
, just as available for rama
services:
- /examples/http_key_value_store.rs:
a web service example showcasing how one might do a key value store web service using
Rama
; - /examples/http_web_service_dir_and_api.rs: a web service example showcasing how one can make a web service to serve a website which includes an XHR API;
For a production-like example of a web service you can also read the rama cli fp
cmd source code.
This is the webservice behind the Rama fingerprinting service, which is used by the maintainers of π¦ Rama (γ©γ) to generate
the UA emulation data for the Http and TLS layers. It is not meant to fingerprint humans or users. Instead it is meant to help
automated processes look like a human.
π‘ This example showcases how you can make use of the
match_service
macro to create aBox
-free service router. Another example of this approach can be seen in the http_service_match.rs example.
In The rama book you can read and learn that a big pillar of Rama's architecture is build on top of the Service concept. A Service
takes as input a user-defined State
(e.g. containing your database Pool) and a Request
, and uses it to serve either a Response
or Error
. Such a Service
can produce the response "directly" (also called βοΈ Leaf services) or instead pass the request and state to an inner Service
which it wraps around (so called π Middlewares).
It's a powerful concept, originally introduced to Rust by the Tower ecosystem and allows you build complex stacks specialised to your needs in a modular and easy manner. Even cooler is that this works for both clients and servers alike.
Rama provides an HttpClient
which sends your Http Request
over the network and returns the Response
if it receives and read one or an Error
otherwise. Combined with the many Layers (middleware) that Rama
provides and perhaps also some developed by you it is possible to create a powerful Http client suited to your needs.
As a π cherry on the cake you can import the HttpClientExt
trait in your Rust module to be able to use your Http Client Service
stack using a high level API to build and send requests with ease.
π‘ The full "high level" example can be found at /examples/http_high_level_client.rs.
use rama::http::service::client::HttpClientExt;
let client = (
TraceLayer::new_for_http(),
DecompressionLayer::new(),
AddAuthorizationLayer::basic("john", "123")
.as_sensitive(true)
.if_not_present(),
RetryLayer::new(
ManagedPolicy::default().with_backoff(ExponentialBackoff::default()),
),
).layer(HttpClient::default());
#[derive(Debug, Deserialize)]
struct Info {
name: String,
example: String,
magic: u64,
}
let info: Info = client
.get("http://example.com/info")
.header("x-magic", "42")
.typed_header(Accept::json())
.send(Context::default())
.await
.unwrap()
.try_into_json()
.await
.unwrap();
The rama crates avoid unsafe_code
, but do make use of it for some low level primitives (e.g. http core)
or indirectly because of bindgens to C (e.g. boring).
We also make use of cargo vet
to audit our supply chain.
Rama (γ©γ) is developed mostly on MacOS M-Series machines and run in production on a variety of Linux systems. There is no windows support, and neither do we test on that platform.
platform | tested | test platform |
---|---|---|
MacOS | β | MacOS Apple Silicon (developer laptop) and macos-12 Intel (GitHub Action) |
Linux | β | Ubuntu 22.04 (GitHub Action) |
Please open a ticket in case you have compatibility issues for your setup/platform. Our goal is not to support all possible platformns in the world, but we do want to support as many as we reasonably can.
Rama's MSRV is 1.80
.
Using GitHub Actions we also test if rama
on that version still works on
the stable and beta versions of rust as well.
Please refer to https://github.com/plabayo/rama/milestones to know what's on the roadmap. Is there something not on the roadmap for the next version that you would really like? Please create a feature request to request it and become a sponsor if you can.
Rama (0.2
) was featured in a π» Rustacean episode on the 19th of May 2024, and available to listen at https://rustacean-station.org/episode/glen-de-cauwsemaecker/. In this episode Glen explains the history of Rama, why it exists, how it can be used and more.
This project is dual-licensed under both the MIT license and Apache 2.0 License.
π Thanks for your help improving the project! We are so happy to have
you! We have a contributing guide to help you get involved in the
rama
project.
Contributions often come from people who already know what they want, be it a fix for a bug they encountered, or a feature that they are missing. Please do always make a ticket if one doesn't exist already.
It's possible however that you do not yet know what specifically to contribute, and yet want to help out. For that we thank you. You can take a look at the open issues, and in particular:
good first issue
: issues that are good for those new to therama
codebase;easy
: issues that are seen as easy;mentor available
: issues for which we offer mentorship;low prio
: low prio issues that have no immediate pressure to be finished quick, great in case you want to help out but can only do with limited time to spare;
In general, any issue not assigned already is free to be picked up by anyone else. Please do communicate in the ticket if you are planning to pick it up, as to avoid multiple people trying to solve the same one.
π‘ Some issues have a
needs input
label. These mean that the issue is not yet ready for development. First of all prior to starting working on an issue you should always look for alignment with the rama maintainers. However theseneeds input
issues require also prior R&D work:
- add and discuss missing knowledge or other things not clear;
- figure out pros and cons of the solutions (as well as what if we choose to not not resolve the issue);
- discuss and brainstorm on possible implementations, desire features, consequences, benefits, ...
Only once this R&D is complete and alignment is confirmed, shall the feature be started to be implemented.
Should you want to contribure this project but you do not yet know how to program in Rust, you could start learning Rust with as goal to contribute as soon as possible to rama
by using "the Rust 101 Learning Guide" as your study companion. Glen can also be hired as a mentor or teacher to give you paid 1-on-1 lessons and other similar consultancy services. You can find his contact details at https://www.glendc.com/.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in rama
by you, shall be licensed as both MIT and Apache 2.0,
without any additional terms or conditions.
Special thanks goes to all involved in developing, maintaining and supporting the Rust programming language, the Tokio ecosystem and all other crates that we depend upon. This also includes Hyper and its ecosystem as without those projects Rama would not be. The core http module of rama is a specialised fork of hyper
and use the underlying h2
and h3
crates as dependencies.
Extra credits also go to Axum, from which ideas and code were copied as its a project very much in line with the kind of software we want Rama to be, but for a different purpose. Our hats also go off to Tower, its inventors and all the people and creatures that help make it be every day. The service concept is derived from Tower and many of our layers are a Tower fork, adapted where required or desired.
An extra big shoutout goes also to the online communities surrounding and part of these ecosystems. They are a great place to hangout and always friendly and helpful. Thanks.
Rama is completely free, open-source software which needs lots of effort and time to develop and maintain.
You can become a regular financial contributor to Rama by paying for a monthly subscription at polar.sh/plabayo. In case you want a specific github issue to be resolved or like you can also fund issues via that platform. One time contributions are possible as well and greatly appreciated.
Alternatively you can also become a (monthly subscriber) sponsor or pay a one-time donation via Github Sponsors. For one-time donations you are also free to use "Buy me a Coffee" or "Paypal Donations" in case you are more at ease with any of these.
Sponsors help us continue to maintain and improve rama
, as well as other
Free and Open Source (FOSS) technology. It also helps us to create
educational content such as https://github.com/plabayo/learn-rust-101,
and other open source libraries such as https://github.com/plabayo/tokio-graceful and https://venndb.rs.
Next to the many unpaid developer hours we put in a project such as rama
,
we also have plenty of costs, such as services ranging from hosting to Docker,
but also tooling for developers and automated processing. All these costs money.
Sponsors receive perks and depending on your regular contribution it also allows you to rely on us for support and consulting.
Finally, you can also support us by shopping Plabayo <3 γ©γ
merchandise ποΈ at https://plabayo.threadless.com/.
We would like to extend our thanks to the following sponsors for funding Rama (γ©γ) development. If you are interested in becoming a sponsor, you can do so by becoming a sponsor. One time payments are accepted at GitHub as well as at "Buy me a Coffee". One-time and monthly financial contributions are also possible via Paypal, should you feel more at ease with that at "Paypal Donations".
If you wish to financially support us through other means you can best start a conversation with us by sending an email to [email protected].
Rama (γ©γ) is bundled with Http/Tls emulation data, gathered for all major platforms and browsers using real devices by BrowserStack. It does this automatically every day by using our public Fingerprinting service which is hosted together with a database on fly.io.
We are grateful to both sponsors for sponsering us these cloud resources.
π€ Enterprise support, software customisations, integrations, professional support, consultancy and training are available upon request by sending an email to [email protected]. Or get an entireprise subscription at polar.sh/plabayo.
These type of contracts are another way for you to be able to support the project and at the same time get serviced for your own needs and purposes.
Rama is licensed as both MIT and Apache 2.0, as such you are free to use and modify the source code for any purposes, including commercial goals. That said, we would appreciate it if you would consider becoming a sponsor of the project if you do end up using it for commcercial reasons.
While there are a handful of proxies written in Rust, there are only two other Rust frameworks specifically made for proxy purposes. All other proxy codebases are single purpose code bases, some even just for learning purposes. Or are actually generic http/web libraries/frameworks that facilitate proxy features as an extra.
Cloudflare has been working on a proxy service framework, named pingora
, since a couple of years already,
and on the 28th of February of 2024 they also open sourced it.
Rama is not for everyone, but we sure hope it is right for you.
If not, consider giving pingora
a try, it might very well be the next best thing for you.
Secondly, ByteDance has an open source proxy framework written in Rust to developer forward
and reverse proxies alike, named g3proxy
.
Available at https://ramaproxy.org/book/faq.html.