No description
Find a file
eternal-flame-AD 565304c7b2
add more identifiable alias for TLS backend feature flag
Signed-off-by: eternal-flame-AD <yume@yumechi.jp>
2025-03-14 17:05:14 -05:00
.vscode fix a breakage by explicitly requesting format guessing 2025-03-14 07:26:46 -05:00
benches experimental URL filtering 2025-03-05 07:26:19 -06:00
crates/yumechi-no-kuni-proxy-worker-build Fix incorrect domain matching in ublock trie, add user custom rule directory 2025-03-05 22:45:45 -06:00
mac/apparmor more just in case user ran as root defense 2025-03-13 04:09:33 -05:00
res/ublock Fix incorrect domain matching in ublock trie, add user custom rule directory 2025-03-05 22:45:45 -06:00
src set defaults for more config fields 2025-03-14 08:52:43 -05:00
submodules Bump submodules 2025-03-05 21:30:46 -06:00
.containerignore Add container file 2025-03-05 09:10:01 -06:00
.gitignore init 2024-11-13 05:23:22 -06:00
.gitmodules experimental URL filtering 2025-03-05 07:26:19 -06:00
build.rs experimental URL filtering 2025-03-05 07:26:19 -06:00
Cargo.lock jsonl structured logging 2025-03-14 08:08:38 -05:00
Cargo.toml add more identifiable alias for TLS backend feature flag 2025-03-14 17:05:14 -05:00
Containerfile Add container file 2025-03-05 09:10:01 -06:00
deny.toml Bump deps to latest, remove unnecessary workaround 2025-03-05 08:09:57 -06:00
LICENSE init 2024-11-13 05:23:22 -06:00
local.toml fix a breakage by explicitly requesting format guessing 2025-03-14 07:26:46 -05:00
README.md add more identifiable alias for TLS backend feature flag 2025-03-14 17:05:14 -05:00
wrangler.toml fix a breakage by explicitly requesting format guessing 2025-03-14 07:26:46 -05:00

Yumechi-no-kuni-proxy-worker

This is a misskey proxy worker for ゆめちのくに (Yumechi-no-kuni) instance. Runs natively on both local and Cloudflare Workers environments!

It has been deployed on my instance for since 11/14 under the AppArmor deployment profile.

Currently to do:

  • Content-Type sniffing
  • Preset image resizing
  • Opportunistic Redirection on large video files
  • Structured logging in either human-readable or JSON format (log_jsonl feature) (NOTE: doesn't work reliably on Cloudflare Workers free plan for some reason, help from someone with a paid plan would be appreciated)
  • RFC9110 compliant proxy loop detection with defensive programming against known vulnerable proxies
  • HTTPs only mode and X-Forwarded-Proto reflection
  • Cache-Control header
  • Rate-limiting on local deployment
  • Read config from Cloudflare
  • Timing and Rate-limiting headers (some not available on Cloudflare Workers)
    • Tiered rate-limiting
  • Lossy WebP on CF Workers (maybe already works?)
  • Cache results
  • Handle all possible panics reported by Clippy
  • Sandboxing the image rendering
  • Prometheus-format metrics
  • URL summarization replacement (local only for now)
    • Experimental URL filtering using UBlock Origin privacy filter rules
  • Experimental video thumbnail generation

Spec Compliance

This project is designed to match the upstream specification, however a few deviations are made:

  • We will not honor remote Content-Disposition headers but instead reply with the actual filename in the request URL.
  • Remote Content-Type headers will only be used as a hint rather than authoritative, and resniffing is unconditionally performed using the file utility database using purely masked signature matching.
  • SVG rasterization is removed from the proxy in favor of sanitization and CSP enforcement.

Demo

Avatar resizing

Preview at:

CF Worker: https://yumechi-no-kuni-proxy-worker.eternal-flame-ad.workers.dev/proxy/avatar.webp?url=https://media.misskeyusercontent.com/io/274cc4f7-4674-4db1-9439-9fac08a66aa1.png

Local: https://mproxy.mi.yumechi.jp/proxy/avatar.webp?url=https://media.misskeyusercontent.com/io/274cc4f7-4674-4db1-9439-9fac08a66aa1.png

Image:

Syuilo Avatar resived.png

Syuilo Avatar resived.png

SVG rendering

CF Worker: https://yumechi-no-kuni-proxy-worker.eternal-flame-ad.workers.dev/proxy/static.webp?url=https://upload.wikimedia.org/wikipedia/commons/a/ad/AES-AddRoundKey.svg

Local: https://mproxy.mi.yumechi.jp/proxy/static.webp?url=https://upload.wikimedia.org/wikipedia/commons/a/ad/AES-AddRoundKey.svg

AES-AddRoundKey.svg

AES-AddRoundKey.svg

Setup and Deployment

  1. Clone this repository. Load the submodules with git submodule update --init.

  2. Install Rust and Cargo, using rustup is recommended.

  3. Choose your feature set, see Feature Configuration for details:

  4. IF deploying locally:

    1. Edit local.toml to your liking. The documentations can be opened with cargo doc --open.

    2. Test run with cargo run --features "env-local ${EXTRA_FEATURES}" -- -c local.toml. Additional features apparmor and reuse-port are available for Linux users.

      If you do not use the apparmor feature, you need to remove the apparmor stanza from the configuration file or the program will refuse to start. The reuse-port feature is not necessary but may improve performance on Linux in high-traffic environments.

    3. Build with cargo build --features "env-local ${EXTRA_FEATURES}" --profile release-local. The built binary will be in target/release-local/yumechi-no-kuni-proxy-worker. You can consider setting RUSTFLAGS="-Ctarget-cpu=native" for better performance. Be prepared for ~5 minutes of build time due to link time optimization.

    4. The only flag understood is -c for the configuration file. The configuration file is in TOML format. However, the RUST_LOG environment variable will change the log level. The log level is info by default if the environment variable is not set.

    IF deploying to Cloudflare Workers:

    Firstly I don't recommend deploying using the free plan because there are much faster implementations that do not or almost do not perform any Image processing. The reported CPU time by Cloudflare is consistently over the free plan limit (which is only 10ms! probably not even enough for decoding an image) and will likely be throttled or terminated once you deploy it to real workloads. The paid plan is recommended for this worker.

    1. Add the wasm target with rustup +$(cat rust-toolchain) target add wasm32-unknown-unknown.

    2. Have a working JS environment.

    3. Install wrangler with you JS package manager of choice. See https://developers.cloudflare.com/workers/wrangler/install-and-update/. npx also works.

    4. Edit wrangler.toml to your liking. Everything in the [vars] section maps directly into the config section of the TOML configuration file.

    5. Test locally with wrangler dev.

    6. Deploy with wrangler deploy --outdir bundled/.

Feature Configuration

Here is an overview of features intended to be configured by end users, see Cargo.toml for the full list.

Deployment Environments (enable only one of the following)

  • env-local: Local deployment with a reasonably sensible feature set that most users will want.
  • cf-worker: Cloudflare Workers deployment with a minimal feature set.

Optional Enhancements

  • TLS Support (one of the following MUST be set in local deployment or HTTPS will not work):
    • tls-rustls (alias of rustls): Use Rustls (does not depend on a native SSL library, statically linked by default)
    • tls-native (alias of default-tls): Use native TLS implementation (requires a native SSL library, dynamically linked by default)
  • Security:
    • sandbox-apparmor: Enable AppArmor sandboxing (Linux only)
  • Processing:
    • url-summary: Enable URL summarization

    • url-filter: Enable URL filtering with uBlock rules

      TIP: Place your additional privacy rules in res/ublock/*.user.txt and they will not be tracked via Git.

    • ffmpeg: Enable video processing (local env only, experimental)

    • lossy-webp: Enable lossy WebP compression (requires a C compiler for your target architecture)

  • Logging:
    • metrics: Enable Prometheus metrics endpoint at /metrics
    • log-jsonl: Change the log format to JSONL

AppArmor

AppArmor is a Mandatory Access Control Linux security module that can be used to heavily restrict the actions of tasks.

It is much more secure than Docker and I recommend using AppArmor instead of Docker for isolation, mainly because:

  • Docker is not designed for security but for convenience.
  • Docker only creates a new namespace but do not actually police the actions of the task and will expose much more kernel interfaces to the task.
  • There is no dynamic privilege reduction in Docker, so if the image parsing is compromised at the very least your whole container is compromised.
  • AFAIK there are no known bypasses for AppArmor, but there are known bypasses for Docker.

To use AppArmor, you need to have the apparmor LSM loaded into kernel (should be just a kernel parameter) and load the mac/apparmor/yumechi-no-kuni-proxy-worker profile into the system. You might want to adjust the path to your binary and configuration file, or alternatively use the systemd AppArmorProfile directive to confine the worker.

All major distros should have an easy-to-follow guide on how to do this. Typically add a kernel parameter and install a userspace tool package.

This will create a highly restrictive environment: try it yourself with aa-exec -p yumechi-no-kuni-proxy-worker [initial_foothold] and see if you can break out :). And that is just the first layer of defense, try the more restrictive subprofiles:

  • yumechi-no-kuni-proxy-worker//serve: irreversibly dropped into before listening on the network begins. Restrict loading additional code and access to configuration files.
  • yumechi-no-kuni-proxy-worker//serve//image: absolutely no file, network or capability access.

Docker

If you still for some reason want to use Docker, you can use the Dockerfile provided.