v0.34.14
This commit is contained in:
1 parent
5c2e50ec06
commit
62b7574553
19 files changed
+563
-139
No files matched your search
@@ -1,6 +1,6 @@
|
||||
# RustProxy source and documentation maintenance
|
||||
|
||||
Current source version: **0.34.13**. The Cargo package and binary are named `rust-proxy`.
|
||||
Current source version: **0.34.14**. The Cargo package and binary are named `rust-proxy`.
|
||||
|
||||
Before editing, read [README.md](README.md), [ROADMAP.md](ROADMAP.md), the relevant [documentation guide](docs/README.md) and the actual code and tests. Historical release experiments are not current specifications. Use the bundled `src/admin/openapi.json` for API routes and payloads; the source implementation is authoritative for runtime behavior.
|
||||
|
||||
|
||||
+8
-1
@@ -1,6 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
Release history focused on **features, settings, default behavior, compatibility and fixes**. Changes to internal code structure and preliminary performance experiments are intentionally omitted. Historical descriptions reflect their respective releases; consult the current documentation for the settings available in 0.34.13.
|
||||
Release history focused on **features, settings, default behavior, compatibility and fixes**. Changes to internal code structure and preliminary performance experiments are intentionally omitted. Historical descriptions reflect their respective releases; consult the current documentation for the settings available in 0.34.14.
|
||||
|
||||
## 0.34.14 — Tinyauth gateway error pages (source candidate)
|
||||
|
||||
- **Tinyauth outage:** when RustProxy cannot reach the Tinyauth verifier (connect, DNS, TLS or transport error), it returns a built-in **502 Tinyauth connection error** HTML page rather than plain `502 Bad Gateway`. The page is local and self-contained; no failed authentication is bypassed and no backend address, certificate detail or transport error is revealed to the caller.
|
||||
- **Tinyauth compatibility patch:** the Nginx verifier now receives one consistent auth-request header set. RustProxy removes ForwardAuth module markers (`X-Forwarded-Host`, `X-Forwarded-URI`) while preserving the verified client IP and original request URL. This resolves the `conflicting auth module headers` rejection introduced in Tinyauth 5.2.0 without disabling anti-spoofing checks. Added regression tests for conflicting module headers and forged client identity. Use the internal `/api/auth/nginx` endpoint.
|
||||
- **Tinyauth timeout:** a verifier request that exceeds the configured deadline returns a distinct **504 Tinyauth timeout** page. Invalid verifier responses, unexpected HTTP statuses and oversized identity/response data return **502 Tinyauth verification error**. All retain no-store and the authenticated-request isolation marker, so Vhost/global error-page overrides do not mask Tinyauth's diagnostic category.
|
||||
|
||||
|
||||
## 0.34.13 — Global security, section-based configuration API and panel UX (source candidate)
|
||||
|
||||
|
||||
Generated
+1
-1
@@ -1925,7 +1925,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rust-proxy"
|
||||
version = "0.34.13"
|
||||
version = "0.34.14"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arc-swap",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rust-proxy"
|
||||
version = "0.34.13"
|
||||
version = "0.34.14"
|
||||
edition = "2021"
|
||||
rust-version = "1.99"
|
||||
description = "RustProxy - independent reverse proxy with local administration"
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
# RustProxy 0.34.13
|
||||
# RustProxy 0.34.14
|
||||
|
||||
RustProxy combines a reverse proxy, static/PHP web server, certificate management and traffic monitoring in one service with a browser administration panel. It supports several domains and backends without requiring a separate proxy configuration language.
|
||||
|
||||
## Changes in 0.34.14
|
||||
|
||||
- Preserves Tinyauth Nginx auth-request compatibility with old and new versions supporting `/api/auth/nginx`.
|
||||
- Uses a separate, locally embedded **Tinyauth connection error (502)**, **Tinyauth timeout (504)** or **Tinyauth verification error (502)** page for failed authorization checks, without allowing access to protected origins. The existing built-in **Bad Gateway (502)** page and all standard HTTP error templates stay unchanged. No extra configuration is needed; HTTP status codes retain their existing meaning (502 for verifier errors, 504 for verifier timeouts).
|
||||
|
||||
## Main capabilities
|
||||
|
||||
| Area | Available features |
|
||||
|
||||
+102
-99
@@ -1,12 +1,12 @@
|
||||
61bf40a0572889dc8b0dda9eae4e93e44b0de9364b3c798106c85700ffb37c23 .dockerignore
|
||||
4140a2956264b44f259e6a37fc00ba02097bbe68b09296e04d3d243c1287129b .env.example
|
||||
9e6356475bf587091bab72246ec9e325b498f7e48a6220e9a18baa50d0a385a6 .gitignore
|
||||
754db9d80640bdb05116d14cf91e1b69bfbbcfee2c522659ace4a4c7d48bb10d AGENTS.md
|
||||
df0f23d242cc45064e2e822bbd1fc8297acffa89f71eed2c0d4314695107d5a1 CHANGELOG.md
|
||||
b548ffccc83f59c886fd111bbfb63b40b34c35889f752e44e586c8e22131cfb8 Cargo.lock
|
||||
bb70eb65066a0aa23859a2ae006ba1bb75ff86b87afd4fa6160eae78a8d42af9 Cargo.toml
|
||||
9a882c75ba505b097de65a1073accd3ccb30395b2454f3c3fb9b25c7b2d9bd6e AGENTS.md
|
||||
3e27930459e3225a19aa5174bb9523df3613c009b7b4fe117311b528f740ec61 CHANGELOG.md
|
||||
11b42e2c29662b09b6ff1a575ec45a98856daa6cbc2c0351afa9f1fa4a11b1b5 Cargo.lock
|
||||
f3cc334705c920f910dbc0fce374b7223c2e6a66abe614cf8074c6e89da1d537 Cargo.toml
|
||||
25c7f3c8162cbf5cc156439774118a81dae9fdc52b611ec7e40c230fc99a772c Dockerfile
|
||||
3b0ef7ac49dfb35375780c53c48c03004fe240e68bb7337d3c8c5ad0a0e15998 README.md
|
||||
750f73027faed6039b06f75f87c5a3c1e646ea396a64750688d2ca1344ab72bf README.md
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 ROADMAP.md
|
||||
da8311e3db945290666324a2f24bf4521b365272d7ac3f862ded1be993eea646 UPDATE_CHECK.toml
|
||||
ac07b3bdd46c787989e93f55ebd6ea3d7f5b150ef36f2422e2b58df3f6b7543a build.rs
|
||||
@@ -27,7 +27,7 @@ d660f46f7ef8c539dd3f5486a31d5a1254b9737be8a278c7f9352c254558f8ac docker-agent/m
|
||||
e52b31d0abf65ae3034f6cb367cca113633014ce8d1d799ad4dd5624d2c7b8bb docker-agent/network.go
|
||||
634790f35ff4627df2a78cec2ed371f6e9ec9df00afb386075595fc7f3ed72eb docker-agent/rustproxy-docker-agent.service
|
||||
5220d669171ec3ad65f50e0bc8de5178dadaa4904def8e1a4f61002aa9e9a55b docker-agent/server.go
|
||||
aa1be1593874450822055e72be2228c914e0b146c04ab8247d7a957afee9da22 docs/ACCESS.md
|
||||
93aa788dc1205bc9386a95a39b30a3862a42ba6a2e90e82fc5bfe681fc7db6a7 docs/ACCESS.md
|
||||
147755fb33e9e91098a4d2dfbe6df8b0d92d602e002d568e64a0f815641be2c2 docs/ACME_PROVIDERS.md
|
||||
ba40dd0ec51e0992c0fecd12934b9875e5e7252eced8db533cb79ec01ac8dcc7 docs/API.md
|
||||
2362ab34020d4e0dcd70e280e9539ef7764b63212856ee08a3a55906c48f6421 docs/API_ACCESS.md
|
||||
@@ -39,20 +39,20 @@ dc670d912a6a946160c2f8528c9bb710ec38ebe406dcb7dcaf18fb2653f667b6 docs/CUSTOM_LO
|
||||
e350c5081085b79e579d1500fa07feee94a709adaf6dfde7b3d9af124a78d184 docs/DASHBOARD.md
|
||||
11a08bf2110bbeabc924eb049a30177a216af5607ccdaf8be9178e751f78a2c4 docs/DOCKER_DISCOVERY.md
|
||||
c891ee5272e2e47e1a8f97133a413e2330844103d543fb5cbcc4d0724d59a1a5 docs/INSTALL.md
|
||||
37001cbf8ed248ca05ec40f12dd9876d33f6e0c97dcb21eb2e6f53c3d97a60bb docs/INTEGRATIONS.md
|
||||
7c97df0b89e230851fe5211f5b295aac1f71a0f64385bf165d2aa7db893fdf74 docs/INTEGRATIONS.md
|
||||
694cb7b15c5bbdc94cecd15dc516c05dcb3467849322cdd125b872d36dee4699 docs/LOGS.md
|
||||
888cdc8c56e10b8a7615012e192e085bf2899d0ec9b3ddfb5731e7de6ab5bcde docs/MIGRATION.md
|
||||
27ba3ed337963d9cd05ba382666eed9c414f58c52e5897b4c1c45603f412b456 docs/MONITORING.md
|
||||
d5894c07c68ec4230987767198434abee13b0e525842fea21bcbe752fa82742b docs/PHP_FPM.md
|
||||
42603310536acefd915f3a629c653664056fa4282801ce0ebae19025b2359649 docs/README.md
|
||||
0f66cef23c9a8caa378497787811edcb4f48e31b72bbd958b2862a9549d78077 docs/README.md
|
||||
490a6dbe870f2b1fd4ec7816768dde6c86fa7957fc9de2d2f075e123c9222222 docs/RESPONSE_DELIVERY.md
|
||||
a7c5b01ad1e6aeb27bccf1085504854b70ed4bf020b481915aafcc4a8aeb1f54 docs/SECURITY.md
|
||||
bbef60ff1771da9f48af812987766e1e479408873ae2f079b13f1d5c62ecc6ff docs/STREAMS.md
|
||||
6508819f181e2a935ffa117451915aa5568a31e2890c57fa10e04543db82f3e7 docs/TLS_POST_QUANTUM.md
|
||||
43a2c6230f95f81bf4efd1575a4f7cdc8b02244df38e19b1ec9c3cd736d3afe6 docs/TRANSPORT.md
|
||||
8542c4a5c9d5dfe474459099546ae590b4c4d3f363f0bba9721c6107643c2d3a docs/TROUBLESHOOTING.md
|
||||
df0d5e9e83ec3827ecf6887801137569118f8f29680b0dda23887723f8d4e030 docs/TROUBLESHOOTING.md
|
||||
e14c02f2c95daf5779d1aa5300751162b63fdd968832a1f0c2f191fa00ace6dc docs/VHOSTS.md
|
||||
25fd98fd7257bb371472ac32cb8d508f5ee3d785a6feb01fc45cc80a3d3afc54 docs/WEB_SERVER.md
|
||||
7e7eab2ba76c262e4000184f80f9a5cb69c7896fe7a046c0d3d84dc211c4b751 docs/WEB_SERVER.md
|
||||
5502e8ce44276213803b66c58e3a4d804a1354f5ed5d83f47ee805e8c44ab088 examples/acl-headers.json
|
||||
2431dd88a2d9ad2cf3cd4b8fcdfa602563ab1013c612d8917fddbe7febfb2dc3 examples/cache-dashboard.json
|
||||
e31ac05a99615e4ea6c4c9a8b2e090968583fe3959f838a600b5740cb170f8c5 examples/config.json
|
||||
@@ -64,7 +64,7 @@ b26833cb4251f9390a44192ecc827ff7f052fd19016a5ccf7498c94503ab4ce3 examples/mock-
|
||||
d242de9614fbb52933b4accd32f4715ca94107abe4a3b1d7e088362b07a6ba60 examples/vhosts-balanced.json
|
||||
af2bdb1343a8141069e94ccd2c7f92574ad848437e2f9fdb5c7576a9a18ef4a5 examples/vhosts-private.json
|
||||
1b8974af79a5026e0648ceab58a32f233e1760e21e7465a0d46e9c41fb09964f grafana/README.md
|
||||
ea8aaf0257a5ab75153ee2fd383a4d5c2ac725c47042f9770949451636d442f1 grafana/rustproxy-overview.json
|
||||
e775dc98b44bb1c362d8de85ffdee105694807a946029544aa13780c806aac33 grafana/rustproxy-overview.json
|
||||
a05cbbf101b288bf9cf83fedfc5017925a8b360a78f313d31c1a70f15dc1dd22 install-debian13.sh
|
||||
909e9ab94617ace74a425f15084bf85f3086cc52ba5b28f2b441ff800abc6ef9 install.sh
|
||||
42f9f1d18c021fc7734b5bd020844bf678725a0e539e2fcbe05ec676f6239eae integrations/README.md
|
||||
@@ -118,7 +118,7 @@ e69813fb1d3a4cdcfb7243964cc323fc21a603087bf2e84188fa42b9d3cee4b5 scripts/runtim
|
||||
046b4282550f5cb4e53906665c91c7442be70fc68fd0743466fd832582f7c979 scripts/test_stream_tcp.py
|
||||
f0b48ec0cc4411755cc0b4128eebce710375afa99344cb76198cf31074f8eb63 scripts/test_stream_udp.py
|
||||
22e880e98c7b9d700c7a4c02b9b1d543e5dbd1f4ecdca42813a1083165b32a19 scripts/version.py
|
||||
5130529d8f55ba9d89c29235a7eac133a80c9e9b2591267b1d082207568abbeb src/acl.rs
|
||||
a6b2c019978e420dae9c4dea3ea46402b51411a589468b75aada8ace6fda9275 src/acl.rs
|
||||
68650bf15c8d1147bcfd49b81fb313171d417100758c1b86a6260c4eeb3f765c src/acl/dynamic/mod.rs
|
||||
1eee2ea2c8dd6068dd0bbb058a06d26436f14767d8efbc2010bbdb4e3e523672 src/acl/dynamic/tests.rs
|
||||
75120cd3115aea6fc40665086617eab9816f08f556cef8db370806195c7641bf src/acl/tests.rs
|
||||
@@ -132,24 +132,24 @@ c51fd51177a476be6462ca980e9bc13f0d0b41538f520118b80a685130f0dbf0 src/acme/runti
|
||||
2f02b08d88ad3c1fc9827e5bd3ef463effba633834d9c05e9c0d6d2a0e8869c5 src/acme/runtime_versions.rs
|
||||
cfc13a293c126bb511745859669719a14c72dd7ff6be197bc9e0d0e560deebbd src/acme/tests.rs
|
||||
b28a08ea996befe10949676f40fab5f1036a274c7d0ab1175cf5c43c59849dc3 src/admin/access.rs
|
||||
69e26e4f06f6084a61b0c40ee2e8d3f027913eaa87d877477f0b9b1fc02589b4 src/admin/api_token_access.rs
|
||||
3afefdc6640d35bd55f20981e842647573f1ba80248680f99ba79eec9a7c4ce5 src/admin/api_token_access.rs
|
||||
5f5b150bb8f51f57462e519650093354ae7b40fcb80c4380fd3391a33f4b30f2 src/admin/api_tokens.rs
|
||||
34e851f725e8605e3c5d9946e56ac035996f3bd9d608169cba3408060d229c9b src/admin/certificate_api.rs
|
||||
4a8b6406a44508b8ba102fef0d8309e871dbe0cbdbee1e6c8721baaca0c1aee1 src/admin/certificate_inspection_tests.rs
|
||||
fe1934fe1ed611277a55485f187a4f62e1fbc3cd196676e64eb1deee4a4c0323 src/admin/certificates.rs
|
||||
521ac794501570cfa2e8e50c3a5cec2ca08ee4dbce8ac9c0e0310c09612f1062 src/admin/config_reload.rs
|
||||
39963903d93ea5b16be834741c7095f7e9bd9fd8fb7dc6ae645d673d0e7f010f src/admin/config_sections.rs
|
||||
b7b0d3f0df7683b031136c05b314e206f7864e70514fe25165e41fd7a9382854 src/admin/config_sections.rs
|
||||
159c3970d25fa29acf2483fc9422b003e5d63884713f62baa8375e4a4020730e src/admin/dashboard_presets.rs
|
||||
aae1ca0e70d987830bd63948d431f54302083148177c1b551565be12df7fe771 src/admin/documentation.rs
|
||||
da28dd57087df138913b784b71dca11d36c68100f2f100f452fbf4e4d7982433 src/admin/documentation/documents.rs
|
||||
6ca14ae276c0e683903cfe326f6733cf33ea05f3abbefd5a22671ea160a58ea6 src/admin/documentation/tests.rs
|
||||
1ce779b84aa8f47bdb3c34f83593c1f2f06d2235f0319847096cfcd035434168 src/admin/file_log_search.rs
|
||||
ab18acf6fb4ac86fb22635b9219a12dac76d24952c8f15538486267a9b4b7855 src/admin/file_logs.rs
|
||||
059218501907355b22bc84e7e0c41ec72565af283f5e97170ce7707ea5874009 src/admin/file_logs.rs
|
||||
d58a2ed83319176de4e66790ed292447c9497ae031464ec55cfe27174acb639a src/admin/file_logs_io.rs
|
||||
282352eda7957477e7da44f16b90984b26a4a67a8755833bc0a6b34eaf93e3af src/admin/file_logs_query.rs
|
||||
444d7715406ffd2305a72decf7fdf633aa4c2752cd881c8fa3b95ed971d79820 src/admin/logging_api.rs
|
||||
243f4a9c3fa99781e19c3952354d2632c0ce65e1dafac729567cbe3c177f94cb src/admin/mod.rs
|
||||
8b5eaeef6ae3f216afae39abed1d47e58ac41bacd1d3e54ab65e0e02f6cda093 src/admin/openapi.json
|
||||
cf7393a5a6c101bc739a4cbf73a2abf60ca8fe2184ec84ae244ef9bd5f99c2e1 src/admin/openapi.json
|
||||
1f4ec45d146e00ef664fae37517f8fcb5455d47daec496c02b2fc15ddec49131 src/admin/operations.rs
|
||||
257d93a29d0bda96462bcf695aba8d0ec0f9412c379e066ec46ae8ee034e3a53 src/admin/panel_assets.rs
|
||||
f5127855c2994d052678865df36d703b74f4a0afc633daf7718b10da18d26e37 src/admin/panel_content.rs
|
||||
@@ -159,13 +159,13 @@ b3c3c2d33c150eb42ce210c6074e5eff6a8af9391118012e413bc9323d3ae50c src/admin/pref
|
||||
62ecbae5dee00aeeca3eb806e2605372471dfab971cde8f66f11e711df8fcea1 src/admin/public/mod.rs
|
||||
7a00e4ab943f74d2b1bdcbfab7f9cd3f584e9f59536b4aca6c4c31f5f5508d12 src/admin/public/tests.rs
|
||||
6930b4f4b45257772b321b20a9becdf9bc4610274852948ba38c2d0cdf02dfaf src/admin/refresh_preferences.rs
|
||||
6d7f3f67b9a0723ba443b09ab3668b5c84bd825613b1200a91b181f9c116977c src/admin/router.rs
|
||||
cc3aa1b094b0d869d141754ac2877817ec40a362acfd7fc3167ea3c9f1ff1a18 src/admin/router.rs
|
||||
e135431cb078ddb483165581123c64af8f00ea67acb3a395ec3e53c85d0d0d45 src/admin/session.rs
|
||||
09cc50a86960897371730cc1abed83f4f640c86b680ec7ff6d6b84c7e96a3c0b src/admin/status.rs
|
||||
2d5b4c28fd0bd48b06890fa8ec44a2296de948c1f88eb2909f4b495710d4e13e src/admin/status_live.rs
|
||||
8315c856cd50f1072593ecb30c274d42d82f078b5fb93e7c68a8857cd81b0841 src/admin/status_system.rs
|
||||
cadd7dca29b9aad8c77c7bc23dd249ea37a15adfa4d636a8ef00273a91ce35dc src/admin/tail.rs
|
||||
0d304b616bd03fbd63bcbd371fae1034ef4e1e9cf28da7320f53d8fd307fc0a8 src/admin/tests.rs
|
||||
d5af049839db73e4d44f2b4455d072c6fb167ac2bd87b3f4aab0ef1d1a2e1209 src/admin/tests.rs
|
||||
c18c369124368f58524652565102817ed69fd25b222b0c5e737ef7632b45dcfb src/admin/web/acl-picker.js
|
||||
48fcd818c522fe80f2c7b2e218f87de6a7772ffd0a24e93502780b03ec78e335 src/admin/web/acme.js
|
||||
86abf50f39862d821cd2e43ca425671aa85289272915132c5a9a5dd1fc4182e2 src/admin/web/api-tokens.js
|
||||
@@ -193,8 +193,8 @@ b7ead49224a4ec67181d3f24f9d9634bd6d76756f826a4d5d993300637d1d8f3 src/admin/web/
|
||||
596205feca534302699120b84848cb0f3e9ef2ad7ba24eac18d5751532a40194 src/admin/web/cache-panel.js
|
||||
e9788a9d1e0bce8775f612a5c842afea8a0dcf01301acdef4b69ff6a52d2ef45 src/admin/web/certificate-api.js
|
||||
9d000e98497b3387641500d5273d23eda45d532c714f22e187572928da152a97 src/admin/web/css/00-tokens.css
|
||||
c6be9f713a97cad7f6d71408944f99f547201a707c277ebc88212ea3823f7065 src/admin/web/css/10-base.css
|
||||
4aae1657e8f5faa755cab0399769e6179364148f80243e742fc7a5e6e237b3e6 src/admin/web/css/20-shell.css
|
||||
51437cbc5ec2d9690a685f9ad1c9235e503049adc4438e1b10ed232a9909b862 src/admin/web/css/10-base.css
|
||||
195a6af7f54f310d936d32b1074e3c5daeaac1a8c687b8dff0223be8ea34eb36 src/admin/web/css/20-shell.css
|
||||
707d08b7b8505c7346d5a98f3a8058f10577ddac7b9e6a5a9894285bde9e300a src/admin/web/css/30-overview.css
|
||||
ce5ffb911d7e4cd2317ca047534921132b6f93efd70a26673f0c428e55320a4d src/admin/web/css/40-editors.css
|
||||
6537a3f97d046b8325c744a281a74f8c4005a8bbcd97284ecf7eb5b6973ae1df src/admin/web/css/50-settings.css
|
||||
@@ -222,6 +222,9 @@ f2cb26eec86b6c03151072f847153df8aea612d840ca8b76367f41b9605bce64 src/admin/web/
|
||||
ff72fc4c6a11907a16234c4b3c7d7f7bcf82eb72868dc3fbf654b04aff806fc8 src/admin/web/error_502.html
|
||||
386b9dc3aecebe7727f7cf7bbd2a02ab036a3abf01315975111a51559128df73 src/admin/web/error_503.html
|
||||
e6c4d91d1542d0a5b47bb8736f9539d43a6713df5a473b635519d5b7eac2eb9c src/admin/web/error_504.html
|
||||
ce598fadd521ee000f05f7d29d70cdeca684a53dbd946a38af204fb2a9248b1b src/admin/web/error_tinyauth_connection.html
|
||||
daa9ef52d96b21c492380486d1cf476c715dcd6c339b431887cc31776de966c8 src/admin/web/error_tinyauth_timeout.html
|
||||
026361d7c3c3b596daa290feaa734f042fabdf236369cd4bebc39795f0c4fc96 src/admin/web/error_tinyauth_verification.html
|
||||
0a5fff35555153f59d4346933030a67b6e1a8768cee7a47cfa2fcf1a2c564f63 src/admin/web/favicon.svg
|
||||
7cbdef9192a9dee1f8eac42b85f52b3190f7f6efae50004aa7ad116a910e4036 src/admin/web/file-logs.js
|
||||
3f0525ca1d4e088ccd4988b8a117b26a8cf8c12213b24c37081d41b68d2b0ff2 src/admin/web/host404.js
|
||||
@@ -254,11 +257,11 @@ b2f948bcc3dbd24952c7b1b02d41d06757f49f0c38a78caf51f8f8a687d8480d src/auth/files
|
||||
25b9f78a7eee277902d375266bd0f023b79794bcdf646214fc161c5e6dab72d1 src/auth/store.rs
|
||||
745226cabb007819370fc6aa680995a03a8a13fa057dacfab0fcc21d0c43bbe4 src/auth/tests.rs
|
||||
32a25e53ac9542424debeaf1b637155bd4e60abd8692df082729d81232eb90b3 src/backup.rs
|
||||
76aa2afe9e7302be39b3512f30d0448d9134300f8ae930d64ada40cf3ad4a8a3 src/backup/archive.rs
|
||||
0f07cac0259e849773466a6fd468fbe84ea34bdb79745dae8ace286b8c707727 src/backup/archive.rs
|
||||
15213c87d4393739328ebf0eacfcb45f864ac12d7bd7509f750a241032f6c7e9 src/backup/ownership.rs
|
||||
37f44cf3ecd71c7e817c76462c4c7de7ca6ecd68c0544f6429a861cdcde1fbdd src/backup/snapshot.rs
|
||||
ece7a5eda4b57bae8f5d819a309cb411b95b1845f5746ac162dee51456365857 src/backup/tests.rs
|
||||
f5afae218f3a6f91bc2f1f5a90094630ce5b7ca574de61807b5a317b13937ec2 src/backup/validation.rs
|
||||
859cec0bcd604f205d7d8e14d1c810e33d97fd7cf00ddcc30877bcea7c5fc2b5 src/backup/tests.rs
|
||||
5293e1b06f82654929805b53b9092a82b7503a54b34da3e882a999c5f14ee579 src/backup/validation.rs
|
||||
eec564a7ef886d18ab75289025a47d62bb702f07d63f92d2f83b7afeecebbb15 src/balance.rs
|
||||
8f7975b488fad31f8d83ffedf8a5b6774b86b59290ce0711e779bf2496d5503f src/balance/health.rs
|
||||
344631248c71164187497a10d177d8eaa3e2f4a08111520d2536ec89ae55e1e0 src/balance/lease_runtime.rs
|
||||
@@ -274,11 +277,11 @@ d789bf40cf9433e2fd16409d112210fe93154588b1ac9bddc9c7f78e1db14426 src/balance/po
|
||||
b75ff512a1c6344483e00d2c67578ceea6b5472c279da0246f3622daa68d7e16 src/cache/cold/cleanup.rs
|
||||
b0ac49535454f50349b5d808c9ebf3a2506c94e63a47dbf802c47fdaacf9ed61 src/cache/cold/cold_tier_tests.rs
|
||||
3c3897980c31a69d96f9295689d1ae19f2190da758c69ee7a0541f4171288bb8 src/cache/cold/demotion.rs
|
||||
e80f84449412c4ae7bc753672a554160519bf1f186b5707252c3286cbe13f02e src/cache/cold/startup.rs
|
||||
17b2a157b03f43f49ed05f1f3391aef025a453b748056c67229cb3ceaa53bb7a src/cache/cold/startup.rs
|
||||
83095bc93132f306c537b31ba929669fedac99af3c4f133d0533b5ed7ac4e6ed src/cache/cold/worker.rs
|
||||
a36a4a255a0fd2c38449bbc462b9c0e21488eae108c70326ab2a0e4c7cee0f97 src/cache/collapse.rs
|
||||
346fdb40d85627b583a01fa17c65e45c822dc7216198cdeadbb3d07904286fa3 src/cache/dashboard.rs
|
||||
54785b64ab4a7b0382b84b4a313d1996c4b6986d69f1e598293f29122afbad33 src/cache/dashboard_tests.rs
|
||||
be3d80cd340edb47755190a668e2f2a2776940665f95ae7110893b706eb94faa src/cache/dashboard_tests.rs
|
||||
8b5a8c04a8ee115497635d2faf08eab5ca4db4225c6c70110675685346f9c0e5 src/cache/fill.rs
|
||||
675d18afb53f25c56cba49bbb431fa39ecd9d7bdd192c7b39b0698225de7a2a2 src/cache/invalidation.rs
|
||||
c1357a13658e1ed5158084d3a41ba9ea906512774a5863ce9c56cb508d3fa6c8 src/cache/invalidation/ban.rs
|
||||
@@ -294,65 +297,65 @@ e9c6ab0c2be9f96573f826e6a1b9e4c2b8b526f779e72e95a6463ae07e45ab55 src/cache/look
|
||||
0c8b0d550e94d4474dcdf991aa0340228dc5f2f904f39350e6e666a16f16fe87 src/cache/model.rs
|
||||
c409174a9aaf20c69dc7b329108d1c26b5672a7341236cf639480df48800d262 src/cache/model/cache.rs
|
||||
0ec4f6d0adea1ed80a3ca17c68c9c85502491da2904d9d690b4169ab9b025b21 src/cache/model/cold_metadata.rs
|
||||
9f3143d99ee7e11abdb625cd8deff0af3ede8af716ea99b754e92803d1150bf7 src/cache/model/entry.rs
|
||||
a6558f1c927b2f2fa0e2536654343a172ebca93ef10363c341cccffa3de0293a src/cache/model/entry.rs
|
||||
ff1c3a1a3bc0d26218dcc943ef951c2a212c180bbf6e4bf1c542ffbf12a9f150 src/cache/model/http_invalidation.rs
|
||||
81938ee9d96891a6e1c81ac1117c67bd4ce4a1530684eab84521b3de1a503dff src/cache/model/maintenance.rs
|
||||
19aaf66abe2ad30b973131a020b7ca8ec6d0646a51df5c604c5f8914db898416 src/cache/model/settings.rs
|
||||
395a82091ae520b78fa606553a0ec590ffb14540b83234cef5bbdcd2e57d39d5 src/cache/model/views.rs
|
||||
f3f8c8116202bb66e3fc7facd0810fd0194838c73ac36e5d372a71549d8aeb6e src/cache/model/maintenance.rs
|
||||
18a2ccfa74a959ec7b41754aaaae073169cf20d9f67e97e8b33191fc706eaaf3 src/cache/model/settings.rs
|
||||
6aa7a03a52508f19ae1ed99036563157eec740b417031933540cab56d35b051a src/cache/model/views.rs
|
||||
e26dce02df9c043329ca164fed215d271781bce8fb03240f528331bf3df6b9d7 src/cache/policy.rs
|
||||
896b1869f94973b30a0de0faa62a2c89fbc8991b02de0e5988ab4ce1f77b392d src/cache/policy/request.rs
|
||||
9dd790a35dbc15df8465664ed9fff296fe22847371d667aefe320504ab952b2b src/cache/policy/response.rs
|
||||
e59efd322f518ebd7b5b154115188f382c2cf7882ca0a401736ba5d685981ea5 src/cache/policy/scope_tests.rs
|
||||
8437aa9097058b1ad19efedb6e2be50822a7f67f05ce3f7182a82665dd1be881 src/cache/policy/request.rs
|
||||
eb64c98d53eb38492810a989e348e5ef10c3c63ed60bc30a1f7e06d62916eb7a src/cache/policy/response.rs
|
||||
12a6d5d9d6711e956391b4b952e8149658b8bf64cfcc0a4c59c281f2630a6aac src/cache/policy/scope_tests.rs
|
||||
4179c2c1367a9c8ea8432bd5815b7e7afbca820d7589742b3ad4775c0cc8e0bc src/cache/range.rs
|
||||
e1d3f0512d6290b0ac4998f47398a0a7c404db249c5bbdbc4ad4767071013a72 src/cache/stats.rs
|
||||
8a300f5dad44815401eb23f4f5a157893761852ba4f3005041e0eb3f16892ce3 src/cache/tests.rs
|
||||
8d9532ea1f30ec431195698a9aba82f2d31083d4b4ee98cb8d9eb47b2b01c7b9 src/cache/tickets.rs
|
||||
3558b10e6bd36a847afffa4ea888ac7cc0a842be128a8503ab18133e79d5e0c0 src/cache/tickets.rs
|
||||
b7c063ed4c8ca96714e1dc5d279f38fc521da2132faad7bd4f40311352a71e7c src/cache/v022_cache_tests.rs
|
||||
452ff2f162f70c3e4d9259de4b13a7751874742c6922c5e0e0196eeadee4ccaa src/cache/varnish_compatible_tests.rs
|
||||
d87f99c48c05ededb0586626d3179391257f54363516119f1567fa0590546485 src/cache/varnish_compatible_tests.rs
|
||||
5a8022f6f4721f9fabdc715e01127d9299d47ee9981a79d26df1981448487d20 src/compression/mod.rs
|
||||
2bb1ea392dc18553a03a6ae1c53f52712ae86571ea31b1bcd93c8fdec2cb60ec src/compression/tests.rs
|
||||
8de82d9188c9c337690c6ec4afdad9fff20651c358e34602a93d8bb8c3d2489a src/compression/tests.rs
|
||||
e695079333ebdc2a6e7b3337cfabef171b3a0a01da0597b77feff70d417f833e src/config.rs
|
||||
9f6272bd6d1f403cf6324b12472fd5c7d911a387139b57105ba1819e48ea0a54 src/config/backend.rs
|
||||
f4df024acdb24be450822e58108af23db3dc82bf1f77531cd16fe340fc01062c src/config/compile.rs
|
||||
fbea01fea1213d98aea812c1b78d5db289e09200b98ae514d742235cd3fa70e1 src/config/internal_routing.rs
|
||||
2669ee64cf00ebe5eeafe37dbbdd963c859f3ced9fea97a00c3f1ba2a42a6e57 src/config/model.rs
|
||||
6e8116efb074397905b41331097cbf81099a21a896b686b4de2e3f210e783620 src/config/model.rs
|
||||
75839458ddbc7480ec4492a95eeb67b617ba7d62f7b67e7a767a3453b74dbcbc src/config/route_policy_tests.rs
|
||||
40e9483d7b2450f55d29b46c408727f4e331b85ecda44fbd7b96bd9a09f02655 src/config/routing.rs
|
||||
dd9a6ad8f58e0cdd1ae74f3f972fee0ac14383cd8b8f518403b9a36c169f35bd src/config/snapshot.rs
|
||||
255b35ca29d25b960d339d2f8088441cea587c556da25de6a159d93f944a9eea src/config/tests.rs
|
||||
ba5829a5fb65e76e2e3450e897eb2d21105809f1d5e16b630a6faca27ca14252 src/config/tests.rs
|
||||
f35de0ee1516ece6bbfd2b2a7db7d1e0f5048b0ec47cf2a3765dffb799abfd93 src/config/transport_tests.rs
|
||||
eb04a8922da26e45c9b6005c0cdf1b1ddf2da3c3b680650b22a1d1f16d17a4b2 src/db.rs
|
||||
e0f46d885ed81ce306a110560cdd2c217dadde054986d89fcec835ebf6939d65 src/db.rs
|
||||
c290d0cb02dfa5d2c60ecabac1cfb20c8884e3d14cca1944906c6d8e677f1784 src/db/api_tokens.rs
|
||||
892ec0e5985700cca399c861197f6c9d2f1c823d8d95b88abac9d27ae15a069a src/db/certificate_api.rs
|
||||
5491dd7bb9b3fceac97c4dea63aba6d5c7abcb0fbd06e36ae986e00c79bc07d0 src/db/dashboard_presets.rs
|
||||
2ff744223934685439374572b83fd639bb3eabdbac168bea4a6501a6e9ce0ee0 src/db/history.rs
|
||||
c05a02618d476e4670b4f9930555f199cac776cdf09edb8fcc1a675695b8f99f src/db/tests.rs
|
||||
dada314e1709e960eb2e225b4d10c3cd12606c62c4bc2c0220aec1ba133e4ade src/demo.rs
|
||||
5808205f03401e3f2c7f5c826d5de76e83e4b6f94c64ad3e50f505f985f6d26e src/diagnostics.rs
|
||||
f9e8539223b4f1d254ee960f59cd4dcf719627101dd9e0190fcd7d331b674fa4 src/diagnostics.rs
|
||||
045593a42a6e4f632e5052c655788f0843faa313fc929265b89509f6dfff91ed src/docker.rs
|
||||
93a8a3f6ba12761ddcbd19f22f32fb2c0e6948b660fb774ddd7ebdba9b6562a5 src/docker/client.rs
|
||||
f69087a82cf353e9a92fc97ee96510dbe0382efa1c5e53821d16c455a3eb95a4 src/docker/model.rs
|
||||
810415a436d842b79fa72392cc18977ad9c368d233ce43e135a60119722c9e77 src/docker/reconcile.rs
|
||||
2e8d4841665cc1d29e6262a1789bb64ced1cecd0036681cc1ef7b5d5bfe22065 src/docker/tests.rs
|
||||
e36db1ed3188ffe54df7fc4ef76c4b453f23683bb7b8cdf601046e2bd50e0403 src/forwarding.rs
|
||||
b496edbfcb8fe7875a95835f8b10a0dbd46775227dbd1e5fee555b284c836216 src/forwarding.rs
|
||||
08d2e08a798abb944a53570f0bdaa08f1266b1107677ceda070091af4c2fc121 src/forwarding/peer_formatting.rs
|
||||
b821e2efd2939cb13d01e402532f33feba6682acb6a7a3223be086c1cd171820 src/forwarding/tests.rs
|
||||
5cef023035309caa5ca2035a11a77cd485f72092ab1c7670398d415460f84bc2 src/geoip.rs
|
||||
80850f7acd1ed4c0048b065e9e81740869a8efbb0d9b5d2e83d8ec7fbc494703 src/geoip/mmdb.rs
|
||||
06aa056d789742cc11c8826c338d985e6a6fb22da6c3530937eec38e35478034 src/geoip/mmdb_tests.rs
|
||||
d3dc58628683472ef4d205fa5c42f0b7ef83cf90846146d96941cd3b36a40766 src/geoip/tests.rs
|
||||
70091bdf6f38f03b6df8c8c4407c300677e57f293130122503f936500963d37c src/geoip/update.rs
|
||||
c1b49bef28d87712e4c46138e70b52c4bcfb1a00196579031fac043d0b4aaa7b src/geoip/update_http.rs
|
||||
9a912dad0b8d1e10410fd95d0da3684656092ef85cf8b23eda4ffe7fb92921d8 src/geoip/update_tests.rs
|
||||
c3bbae778cbbdc1bb299152813a2513c6c9f9840114b15bc2613908625d9a79a src/geoip.rs
|
||||
f551ab3bece770e772fbad46eb88a1e8bf58db4569a22a57eb0fad99abc41e89 src/geoip/mmdb.rs
|
||||
1e8777b295e6a2de15b55548e8c4c3a4166b1c5af18d4d33bf067d8bece1b590 src/geoip/mmdb_tests.rs
|
||||
cfc75486e69c310fa6e7bf0448ed39a20cdad9dd8afe75e01592fc7c76a380db src/geoip/tests.rs
|
||||
3376ea3d018faa5cb8a69da2f1d5b7cdae4bb4b8f28f373f8a0a2996410e1bb7 src/geoip/update.rs
|
||||
86a16add6757a377264ae6afe071039851d5996e80baca9d4882b71889d7c2d2 src/geoip/update_http.rs
|
||||
618d5f245a9c7a1a95e1d086cc01bd2aa4f0360f85094f1c2403a5c14a6607be src/geoip/update_tests.rs
|
||||
61a2b01db9010f9debfb38b43a26bf588438a5e470dff938e4e54f9d7ba46732 src/headers/mod.rs
|
||||
e4f07bfb7eb75b6897ef812870caff158679a3046d64582428abe8c6df490dbe src/headers/tests.rs
|
||||
3e9a19c221fa7e63d097c185470b17313da7c200a73ce50f6c069b4dddd37a96 src/headers/tests.rs
|
||||
1b291ef7b06647ce820111cc802874394e3600b4b2c86ee9a1fbf7eee6cb864a src/http3.rs
|
||||
0cc484bf0cc59a55a13e0e70435833a9a7a22ad7dfb5b9f86e059cf70a80cc2d src/http3/body.rs
|
||||
741972222414c280104acbcd8f8071bed9cbfcfa2f503c487c11c56f553f53cd src/http3/diagnostics.rs
|
||||
49ce4452ef7973cafa2e4071e2e14be0e16000e931a6501e4dc613652e49e230 src/http3/identity.rs
|
||||
0b41072f6bcf28725c80f471584cd55d4900424ce5d55ac7f6909813788c63fd src/http3/settings.rs
|
||||
5c550075c7b0fe687ad02095c1cad57b46b579fe21dc5371525b6c77db459886 src/http3/tests.rs
|
||||
68fb5ab6a889995a66ad12cb6acf88c5d04f0aca572e2ae15f1a9cd171a5f24b src/lib.rs
|
||||
65cbe42886c89cd6675fe42f2051a8adba6b22d4bd106d93a205321baefd7a01 src/lib.rs
|
||||
e8399753a6ff49b7de19edb0a268bf871c9979a518354160cf07b4669051fcbb src/logging.rs
|
||||
e4be3ad758c3d93ce52dd3b1ab1a87810e5226339400ed997607a5b746354751 src/logging/error_runtime.rs
|
||||
b2ed730006fdc080cf7eafc6d20bb89661c639631c89642d110e0c1319e431b5 src/logging/format.rs
|
||||
@@ -374,7 +377,7 @@ ee401f943bd8b2706c33419ed69102269c08dcb4ceba6f4be2ac0861115874a7 src/metrics/vh
|
||||
9c96c3e4edb20dd0c36b5c373f1925dd60368e75853002206523072d418d5417 src/not_found/mod.rs
|
||||
fa2fc6c6987a8356a9da92cade10db62426d8863e9cef3c0d4324c45780c5b33 src/not_found/tests.rs
|
||||
d32d757ace8753eccb842c24b7af77061141478d10fe0acdfb05263d19e9a64c src/pages/mod.rs
|
||||
9d3f4db663016033c4ba0d86e30367bd5a1ab79c8bc121265d410698104fa19c src/pages/tests.rs
|
||||
0e973bf65f232b5de00f0f39b349a6fe9cec7aa1760184e2474e0c7bde52f7be src/pages/tests.rs
|
||||
5650a3f70162abd97021e0a51a92cac2c4dd39004426ef99dff36cbb0741aeac src/prometheus.rs
|
||||
192a780d5874afc158d62a7dbe1687d734635afe9342fff526b8a2f6db4e5633 src/prometheus/core.rs
|
||||
2321ee667569803dfe6c92c0e98adba0ac8fcdc6a3eacd5857233f1acae93daf src/prometheus/docker_misc.rs
|
||||
@@ -382,17 +385,17 @@ cc909edf740a091f9057912f555dd888b644fa1cb49647fe0e2e1f5dba8ff5af src/prometheus
|
||||
f9aab3297fcf647295849f77cbf99197f4dd27efd6817e54c03451e04972430c src/prometheus/model.rs
|
||||
2ea975c96fb45bfeeda95583e909abb26328a16e411fa46a1e31b2a359f7e711 src/prometheus/tests.rs
|
||||
028e1dd9f2ec2afaf699a6b21c2d4b0d96e76f11f5e4ed009c233dadf0f3be51 src/prometheus/traffic.rs
|
||||
e03f0d6b3f35dae6b98c394837aa0d17e4d73a8306767b4c607868bc00c30286 src/prometheus/vhosts_backends.rs
|
||||
cdbfa0e7f49200dc70ea6df8f0594399ee3e0c5fc3d279cc336e2d83d0f8a535 src/prometheus/vhosts_backends.rs
|
||||
f1b0254f53b1a4336bd8170ad441ba072b49a114e497b985cb20699b4e375044 src/prometheus/web_php.rs
|
||||
569eda61453affd053fbe24fa59652289cb12d22b77e64caa38325bbea48f7df src/proxy/body/mod.rs
|
||||
57a71c9c6e4e0deba5d05963b9870af8f4c4d8dbd321ed4e52cee88746c997f0 src/proxy/body/tests.rs
|
||||
bbcb1791a0b1dc48ec6f8e37622f1028109e9b614e57466d75c79717ede3cf91 src/proxy/cache_helpers.rs
|
||||
7e3837d2f6ba7d07ca2cbabda57b315f5a7f4d75a13e5eddf6861a150d0d2ed6 src/proxy/cache_http_invalidation.rs
|
||||
d134b0eb617f82f9971b3f3461379ea37c57bd0079bf54748d0c434b2ef1b475 src/proxy/cache_http_invalidation_tests.rs
|
||||
5beeac12ca7f041bdb9b74b2dbc9781f5d5524fcf51294b8b6ad88284754ef20 src/proxy/body/tests.rs
|
||||
e5e32d86780119dd5eec4c8a369cb1aea44904ab62646e04e458640a3e4358eb src/proxy/cache_helpers.rs
|
||||
78caad08c548386958f605f82f6c4299ab94a910a1332a1e0817dc53920c96a3 src/proxy/cache_http_invalidation.rs
|
||||
a86b10ce0707b51e925e11ea14f7f40fa108a196166f62cf40007a97f9e17203 src/proxy/cache_http_invalidation_tests.rs
|
||||
a03b1735daa8fa8e40cf5bd9c6e200d211baf19c30f62522d4237ed56642bce7 src/proxy/cache_plan/mod.rs
|
||||
3404b03096862de1050088f62cdd811ea1ab61d191f902501173107f81f23b9b src/proxy/cache_plan/tests.rs
|
||||
a0b9e2e9ab0bc89c7b64bd19365198234b1c5c13f455ea47be122a5660639b17 src/proxy/error_fallback.rs
|
||||
3efd124f2c27ac2d5b6c6c0ab6a5b91b7b18ce2f3bf097a00fca5475b05e36c0 src/proxy/forward/cache_fast_path_tests.rs
|
||||
11f11fd8131023d7bfeceb6f4cbf169db994e2b6ca1931167f96ae590d8e0e01 src/proxy/cache_plan/tests.rs
|
||||
3ba479d72d0e94263acaf2eb84f4de0ff2b0b455ee6a4d3f04bb869a5a30a103 src/proxy/error_fallback.rs
|
||||
aacc3249b3cbce0726dc16e28ee09d78efc4ac89103675287b1adab870bb4e15 src/proxy/forward/cache_fast_path_tests.rs
|
||||
f7903200756dc6393392560656b23364f0d444d6357d264713b17c63fd8b636b src/proxy/forward/cache_lookup.rs
|
||||
287012c81144d8f15af4a148ce3ca911d431bc59adff44e697567561aa372bb3 src/proxy/forward/h3_navigation_tests.rs
|
||||
a6580dc359d1f377a48ccc1a902056dc5c2ef86c89180b9b0995068d9817ae8a src/proxy/forward/response.rs
|
||||
@@ -401,20 +404,20 @@ a6580dc359d1f377a48ccc1a902056dc5c2ef86c89180b9b0995068d9817ae8a src/proxy/forw
|
||||
744daef016d4a6c821ab12eeedaa2f29e2de72e2ac9dae16481d4f43476cb713 src/proxy/forward/success_prepare.rs
|
||||
e9ac9be64f6f83c4ca2cd5d299649f24dd16197712083c6dc10e55c662c65b80 src/proxy/forward/upstream.rs
|
||||
690ff6a6860a7ca8ecd502657a68e5012b7f176036d6d7033dabc514735dc2f5 src/proxy/forward/web_source.rs
|
||||
a5e2825d3ba1cbdc9d4afbaa133964ba0585fd776dcd8aa98c9817cc027a6b97 src/proxy/forward_entry.rs
|
||||
ffbddc99112148dd28b4a81ec0527f608ce89fb412a0a8e99e26942cef13f9b5 src/proxy/forward_entry.rs
|
||||
9b25f5e3ea4443a63ee6f45d12e1957dd316fe8e85325fc00ea416faaab1025a src/proxy/h2_graceful.rs
|
||||
684ea1e2a7591a17e3c633576fc66e2a30d6636738fbce61dab5af44f2c51a67 src/proxy/headers/authority_tests.rs
|
||||
66efc52d64d34667ba7419f8a2da89d2efb1af1f426684f4fff8caccfdf19996 src/proxy/headers/mod.rs
|
||||
0f9314d1380febe436def36b5f381731e97cbac90625637575f38f3d72eaaace src/proxy/headers/tests.rs
|
||||
c04451ac8abebf4662ccc3ee4610d5342ad5382da2098f7af5db274d079770b6 src/proxy/identity.rs
|
||||
af9b044761a56e8a6dc57f9d760b289ff4a6bf37db11dbfcd3ec4da5b8f426b6 src/proxy/headers/tests.rs
|
||||
9a26952f68cbe94cf1bc4a8ca70776a083b37c599de2297cea126799a1788a3e src/proxy/identity.rs
|
||||
a08ee061e146cb7a08311106f73a04468c89f77b6ad05a2c623621a2ae9faf2a src/proxy/mod.rs
|
||||
5559efb5984e8da34235e2e5cb34cd6865a34ede20e159bc9f04fc9190a5c09f src/proxy/redirect_helpers.rs
|
||||
da9148ce6a60226954cc839f606465b8c16a44806f4d5b2e22ad60484509b967 src/proxy/redirect_helpers.rs
|
||||
de1763b89d98607e20f0f6e3c9b546483927cbe5450efc2e5634fe691fd52ad6 src/proxy/request_id/mod.rs
|
||||
b9a2307c6aa7f16613d935508a61574dfee964020b1b5be86293df2d684615d8 src/proxy/request_id/tests.rs
|
||||
78bbc1263bcd600527bf71acdf5af92bf186267a9084b076d1f75ad6492df659 src/proxy/request_id/tests.rs
|
||||
580fefdc7dfb27da73f86f4d2067d46a1f856d2f398b0598d37a743e880d3dac src/proxy/types.rs
|
||||
37b20f962563babd3602d21ed6326946635281c0b0d97ca59f4e33de170ae93f src/proxy/upstream_helpers.rs
|
||||
56a921ee4f30da154176998a383bcb5a40d3c7784a04829c59b8e6536728e2d4 src/proxy/web_cache_revalidation/mod.rs
|
||||
fdc589ed3968915558a98a11c7cadc36145b5b0b0dca9393613391990d138fc3 src/proxy/web_cache_revalidation/tests.rs
|
||||
3fb4896f2ddf9dad783005e34e6d4ca0032fb5a69ee38865b5e0ecc9d7f97f30 src/proxy/web_cache_revalidation/mod.rs
|
||||
5522456cc85948228250feac92308d53b130c4a7af98d24f669aca4dfe6999b6 src/proxy/web_cache_revalidation/tests.rs
|
||||
3d591201595a3b1e928ded20a8736477a47e5acc3bcbde158f7c17547ce155ba src/proxy/websocket.rs
|
||||
f8972bedb1a487fac86177774cd98cf2619fb25af97e57cfac2853db5cbf91a9 src/proxy/websocket/handshake.rs
|
||||
c02d42b5c7eeedbc54c58e98691f7d8e39f8e9be63a48f6d6b4ad6b8ea431b7e src/proxy/websocket/http2_tests.rs
|
||||
@@ -423,7 +426,7 @@ faedf6cc2bd4c42f342a0aa188b634d6b8d280ca0e121032977eadaecb88e9d7 src/proxy/webs
|
||||
a44421714aab37f7ceda19e3ec2512c645d2a3ce5dcb3da5bc7a0d87a442d6a8 src/proxy/websocket/tunnel.rs
|
||||
999cbf85cb6e917db529e30ba4a5eed1cc9e95a054da7b3039c730bb80061449 src/proxy/websocket/validation.rs
|
||||
80d0f744f7ad9f0d1edeb0d5c23b13cb40431f6b6f4d10d534ed34d4198e3dfd src/rate_limit/mod.rs
|
||||
2fcfa9706eb0708519d5181debaf3c85a86e401a8898df72f9eaf0ab72c9df85 src/rate_limit/tests.rs
|
||||
c85c9f05dac65cde6878bef3ef7258eb9de79ca14c26ca2492e0e13839c40fc3 src/rate_limit/tests.rs
|
||||
e53c40b85792d4804a432e3c97dc13af8e29304bb0d250ee9ab9018bde522eeb src/redirect/mod.rs
|
||||
811c83ae9fd0f5a13d35b5443cd37843f82b9d600bee4bb136ba9b87732a5347 src/redirect/tests.rs
|
||||
244d72b3dab36ec505c96d26a967420714fd3807268820f680fb3dcea0e88c0f src/runtime.rs
|
||||
@@ -431,7 +434,7 @@ e53c40b85792d4804a432e3c97dc13af8e29304bb0d250ee9ab9018bde522eeb src/redirect/m
|
||||
2d610dc36f746215ad3bc1d860ee624a9233886d73a019fd243e51901503fc53 src/runtime/constructors.rs
|
||||
eb2b0eeeb617cad704732d87acb667530144836e26edb0189929b1f25f35c6b5 src/runtime/docker.rs
|
||||
18f7460e3738386e070f66932cd77240001255447a769d6e19a40573254a1473 src/runtime/external_config.rs
|
||||
a3b65ac6133979b2905b878e5634537994816abb79480af219a17896c6dc4e33 src/runtime/tests.rs
|
||||
5999d7e91ee4231da88c5e9c6d8a12ea9f92d20d6dcdb24319f9f90891d7253b src/runtime/tests.rs
|
||||
d7a65497d1faa2f09a09c0a0ef77b444990cfb5ab379c85f6c27c1f9c0c143cc src/runtime/types.rs
|
||||
11e99eb425887ad12b73d949f4b497fabc6897fee8fc7647fcb3766269c2fdc0 src/runtime/updates.rs
|
||||
e3dbd60953db5a976985dd796e4268b41a0f3df59764c4664015bd41e2578058 src/secret_store/mod.rs
|
||||
@@ -439,16 +442,16 @@ e3dbd60953db5a976985dd796e4268b41a0f3df59764c4664015bd41e2578058 src/secret_sto
|
||||
98854bfeb35cc5266210b1c33dffb36b8441e27e61d90ded8b681430696d156f src/security/mod.rs
|
||||
0e5fc2aff856bf6fd959cba12b5ddd1e3b3cbeb0fbaadde906c811cdfafdaae7 src/security/tests.rs
|
||||
0e8589f56e3229dec556b427b87c2cc5a5a9ffaa9ea84fc2522dc72d3239027d src/server.rs
|
||||
ad4cfd4a7d6f331a8ce3bf17a6c461dba788bb41994f667033c6963df3b96332 src/server/http.rs
|
||||
00dbce1ff1ea08774bcfd79d900d71704256e06ab0cc46c379c3d107c99ba50e src/server/http1_connection.rs
|
||||
1cb8260c74de89c3e13bc225da32cd86fe883acd3c720d0cb2fc44c0c55e940c src/server/listeners.rs
|
||||
a64bc0d4352ec8d97895978a98b6b66e0459842d1ec410a1d123d5d29d9ef058 src/server/sendfile.rs
|
||||
4cb5afb53c824f5c87abaa65ba5dc85e937255c4a3dd14af16df9af7e01afb10 src/server/http.rs
|
||||
533342fb3bf8b52743d3a7102ffe345be9f86d553b16a1ec322e468b44b0a7eb src/server/http1_connection.rs
|
||||
8e51738b1a2805c1226f537b85791fb687a52edf870cf2971dd9af75375febf7 src/server/listeners.rs
|
||||
4e94d7cb95ec3e1e7b19884ec11c881e4fda1e57830525356bb1ed44afd6b17d src/server/sendfile.rs
|
||||
5f6a59c6085c1250a93a70020661d1e8174d3b600b494d16f8eaf7941ee3bb99 src/server/serve/mod.rs
|
||||
048a05a46108f50bef7da50b0c03b752d76e586b411de8ca3f55313bbdb08aee src/server/serve/tests.rs
|
||||
669ea1041c103cb952f7a516363c8fe7baf51622f721aabdd57015e0e0279530 src/server/tls_runtime.rs
|
||||
d0af5ee91ff7f0315d347b3fd41d60b41e9dd095e0d015ecd99f17c4f3a923f7 src/settings.rs
|
||||
298673b6407b0ceda6ebc2ad4f4d787688cb0a5f144164f74895c745bcc53aa0 src/settings/public_origin.rs
|
||||
a4fdf54f87bcc96b31e8a0ea400398a70011a044bf2ff3de78a0489b767f9de3 src/settings/tests.rs
|
||||
d7f52ea1f6c0d037fc92d17872ec38df589815f9d7fbb038e9c1cc584d3534c4 src/settings.rs
|
||||
b2e2924047019b1ada59c58a4060476151c99be12c0b4092f2cfd201c0756255 src/settings/public_origin.rs
|
||||
a6a1cc42f0a5e40071b3683ee517c39f3c006ff3843dffaeb49391d58518c4ad src/settings/tests.rs
|
||||
2ad7888b263e1dd9f0bd588dc35590c9eb232f8fbacd10ea7554cb55b4dbd25b src/stream.rs
|
||||
c7771539fbb94544947e958e410c46b73f9647011e56b1b229ce7035fe21851f src/stream/health.rs
|
||||
c02e85af45590866f20933561f85ea9b4f2ead62c2ce41db75113632670a7b5f src/stream/model.rs
|
||||
@@ -459,18 +462,18 @@ c02e85af45590866f20933561f85ea9b4f2ead62c2ce41db75113632670a7b5f src/stream/mod
|
||||
d9123c623e2a97d09e41edaa29993b4b2c8cba39a3abdf2b48a205aa9a9c2939 src/system_stats/linux/tests.rs
|
||||
2c7da96822d605193f0208df70de670612259fd8c762c998ae828848cb210e11 src/system_stats/mod.rs
|
||||
050aa831b1012c4aaade63863f433f01bfacf5d3f95787e57975572116a30ab2 src/system_stats/tests.rs
|
||||
e7ed064a1706de9a7345e41fb8b6288b4467c12d1653e8afba6dc392c7a3a36a src/tinyauth/mod.rs
|
||||
0e1d87554db55e724f30c41ec4a5c80bdb8fc9c8cba8700ac509864d4abf8871 src/tinyauth/tests.rs
|
||||
f0a1109bf7be0dd6a8734be9d47221d99ac993ebfe8f73508191369db69cebcf src/tinyauth/mod.rs
|
||||
e2ab9180f25b1f3c2723ff5a40d35a5a395a188481b766f2730b18e07500a636 src/tinyauth/tests.rs
|
||||
df98becda799b6bf4ff5e2fec7d0e0a486e6b7eca6f9f5ad49ffdafd49a4f498 src/tls.rs
|
||||
2af2164ecdf2b7fd9eef7c6e358dec053dfac9aedaa501dbb75df742d18638b2 src/tls/acme_tests.rs
|
||||
7425ee6c839f85d792e9251c6b9039e72fb49a5820a2266f751e6f4967a5871c src/tls/certificates.rs
|
||||
84e3da17c59cc90e8575af8158ef4134cd058446a186df675d60106c53dd55ec src/tls/certificates.rs
|
||||
b59a62d723c8683ebd7bb2d2d777d9451064af20b254b98a8c4b9eedfd74bd86 src/tls/external_paths.rs
|
||||
8d14216afdae33b9dffeb5145d92b8c6fd224c3f8f2baca0cf007b70541daa86 src/tls/external_paths_tests.rs
|
||||
7b4c0f58b3a1e1791bb3c682a001b78bfdbbdafdbc143db8063b3f22dc168616 src/tls/server_config.rs
|
||||
b705c6e5b2bd9eac2dd310478fdad1ca47610b80dd2d8c91516fb639b0dc2a5e src/tls/server_config.rs
|
||||
7c0c06c3009c726043168ae47254a84642dbabbbce1b2e718544414312ca3e9b src/tls/tests.rs
|
||||
d625e2e3f669484432ffc0bf7c1aba94aa5bb709dc4d080daa3bfa8004dee9f2 src/tls/types.rs
|
||||
a535c8526b38de2990da7781e158b9ea70ef8c1f6fae0aac5ce6e9da21d3a309 src/traffic/mod.rs
|
||||
dc8a83fae47da0d86e6ce0a329cb5274233264df56eebdb56b9bf37cb7be2bb4 src/traffic/tests.rs
|
||||
bd62b4ecdcf831d183c7720766a11703c8612d614e3abf38d2bff28df34710fd src/traffic/tests.rs
|
||||
65fcac840f8b5f1508213e3f374aa318b450b0f9f90ba827c5ea935b9c60bee7 src/transform/apply.rs
|
||||
34a06c2dc635e80690961ef61fe84110f9578f55adf89f92a04668783ccb0a98 src/transform/compile.rs
|
||||
5a16b628af31fced425903a9d4b6ee83e1fe06ba023d574db16467baefe00ad3 src/transform/css.rs
|
||||
@@ -484,47 +487,47 @@ d13fa462d6df516a4cfaee9f4e184044c5b6345e311aeb3d9058efafe54e4c5e src/transform/
|
||||
954b86300c3ea47281acb2f43b0771e838f83ac09eb55e882e42de26aee3128f src/transform/model.rs
|
||||
4b52257e1a3643910b5e7043852d7218230c0021c31215d90d0f8e384f2ae233 src/transform/svg/mod.rs
|
||||
0f53c64f442390ee20a59087a10f8f9ffb58053263e9aa848ddabfae1a6f3f51 src/transform/svg/tests.rs
|
||||
3c99de898e4c516a805fec1bc77007a211550b7d7a563933a81ae635d235a2e6 src/transform/tests.rs
|
||||
88cd3729caaa48453d7f9e337052fa85c8a74498460a71e2dbe73245c78ccc8d src/transform/tests.rs
|
||||
8d38f2f7d4ca4dd453cd0e2337614ec704fbd0a36d3e2374cda43f05dfcad663 src/update_check/mod.rs
|
||||
c42d000d1d576721af3ffe930589388693001b8113554a7658f6dcbc665b5d1b src/update_check/tests.rs
|
||||
b7ee3629a8fde0972bc1822b764f5fa2c813a760dd5dfb7f1ce643a7db8f9f75 src/upstream.rs
|
||||
fe9d4deb34cea2408ac5a1030315989f29a6a7d078a46ac1b59d12aa07f67878 src/upstream/client.rs
|
||||
eb513923f8951c8bf30bad3cbac77d34f5ebbc7af3ba69a08a25bae834f8a016 src/upstream/client_tests.rs
|
||||
8c88d928b823e4b6ba6d852f74664c770d8b3fce32bc76c583dc1f672fe33f14 src/upstream/protocol_tests.rs
|
||||
165e048e2b302af28988c1a23f0e88c989c3cf093fc8b36547070871390d8376 src/upstream/client_tests.rs
|
||||
56b1e4242f8153391cd9a01fbb3017a2dbda9d02e83da6bbfb39ed44854534b5 src/upstream/protocol_tests.rs
|
||||
ae880b40197454ea3fbf4d2113984dc372098b2e54b97e87c83cc319de253377 src/upstream/tests.rs
|
||||
5c42f1befec267293b6f03eada118a11c90adfb4b32e0134d7f0033c7453c7cc src/user_agent/mod.rs
|
||||
6d7cb73de7d8c6f3780736480f5f81ef08813f4626fd5ed494aca0552cf214a1 src/user_agent/tests.rs
|
||||
696a2783a24f7f3d69fb820dc3a772ec49ea46ee017087952a8253363a9b7374 src/user_agent/tests.rs
|
||||
d61c427c1e9cf457f1232b822d73e846e9f329cfbe61215e7ca061d53762155d src/vhost.rs
|
||||
54b0c1d2f04e5c654123c3422645eb5a0a9609141cc4a1c6addca2d028392772 src/vhost/error_fallback.rs
|
||||
846707452ccf10962f1763be66b8f56c050b0398b48968015fb799dac289c0d6 src/vhost/error_fallback.rs
|
||||
9d358be766f767d9e1a42f585edcf7fc1cba8f22e5eaac294a83920425ec03c7 src/vhost/model.rs
|
||||
e003b935d91791f20d80c59bb46f9bb0820694dcea5d95e65364b53b016284ef src/vhost/redirect.rs
|
||||
fc8af7342a3b147921e9040116af5dfe680b3df910db2416ada18198bbeea7df src/vhost/redirect.rs
|
||||
dd6e121445402a2ac8744f0e4f23d879b4356f47c1bb00737bd15ba459661978 src/vhost/tests.rs
|
||||
c95cc8f4549460917633a12ccb352a00a83c0f004b23c0b9ddecba42eee3ea17 src/vhost/validation.rs
|
||||
a69e6138d77ead1558eb9303c68dc317bdfaadbe297fe973d62d4dba41afae73 src/vhost/validation.rs
|
||||
8d1eff4b24f01d137414ef5419f75dd281879228adb70409645b11b3c78c20e9 src/web_server/config.rs
|
||||
9744e8c29ae72a4d9fbc9a76166a97f8292c4c312295ea40d1cb699e03d80a9d src/web_server/config/compile.rs
|
||||
daeb5e05e4129764102b3f04e62b2dde38a8c7739bb475a13bc8c8f6d5844da1 src/web_server/config/model.rs
|
||||
5ed79fa5b9c53f95ca200d89a9ba927dda816b61fbdf3b852bd3c9670e3d2d4f src/web_server/config/model.rs
|
||||
a863ad1337fbc353c0f42caea4ac8b3644792e2aa08c37f992b7882b4b8dc6d5 src/web_server/config/validation.rs
|
||||
86c744216d7132d8294a6e90ba9be5fd871646006313d1c62506d40c81db9b12 src/web_server/fastcgi.rs
|
||||
002071ef603f1d928a56226b011c76ac5ea2bc55521a0a3fd317c0ced0056c21 src/web_server/fastcgi/protocol.rs
|
||||
e954308d94848471f6a9d70a50cd2181d17b9c41b2705a3e6c6c0e882a03733b src/web_server/fastcgi/response.rs
|
||||
b98666353e4af560ab8423d4772d9ad26451dabb1c6d60f5faf547116a2bcd24 src/web_server/filesystem.rs
|
||||
1ce9c3797f50cb9f27a945fffd1890d9d8e034048c8d4df93a3903905eec1207 src/web_server/fastcgi/response.rs
|
||||
92d2ab4d7ecb766bbc705f8eba94c1ca33347ffb84b36e0ad0eccfed5915473f src/web_server/filesystem.rs
|
||||
d4fec3682532b0f2d11a0aefcd024f69fb623a39922ddb6c528a2d2de265347d src/web_server/htaccess.rs
|
||||
66b846cce61345ea6d182db03e4f8eddc5d4a3cbe87f2046523310f1ea13a5a3 src/web_server/htaccess/model.rs
|
||||
b4646f705e532f682d6152b6827cc7f4f915766ebcb4af89eba9950965673772 src/web_server/htaccess/model.rs
|
||||
9c57b7c556984f79404d4afeb9841d0280a198b94c42d887bc6d96b7748a0e67 src/web_server/htaccess/parse.rs
|
||||
66260d159986d41eab0dfde2cb9f0713fc1cc209c2fb47e9023bd24fd37919e8 src/web_server/htaccess/rewrite.rs
|
||||
6e58e2674940bb0284035856fe9299a0555fee4c566de75e174deb373c3b164f src/web_server/htaccess/rewrite.rs
|
||||
8ca74d9cc4470045301f70eb4a9fbabd0dbfe74434429148d2230df9f996c06c src/web_server/htaccess/tests.rs
|
||||
b4a75519d9c7bb4f176126a284ea5da68fe512674200765da0984b245e4278ba src/web_server/metrics.rs
|
||||
7fe32af33b4d8e079ad724665aa1cfb62f6e98b9406b77168feaac55dac36137 src/web_server/metrics.rs
|
||||
029bc2b277b2fd7528d5c9f5637453ce6d1d3ec2df7e441f6844cf55edef6b5b src/web_server/mod.rs
|
||||
67ab8bef567452f123c4b9b46a942b39c93f1f765c128edca7ee808ff1c5e304 src/web_server/request.rs
|
||||
e9ba6e09ba2c8f8a33410c219d5ea29214cc53e279a43b17c110d24f17a5a71d src/web_server/request.rs
|
||||
d98c80663847d6d83073df074ebff65952755415574708abcc153bd8d3adfaa9 src/web_server/response.rs
|
||||
c69502a28eec224eeded7cad93159aae3e7c136721a19f4542d5f682e055f61b src/web_server/response/file.rs
|
||||
cbeb022847e64d30e9d63aac92bee00d29281b3602e1a0589f3c978cbc7c2238 src/web_server/response/file_body/mod.rs
|
||||
4e91d09fa086d388e384d14b347eff8c74c010915ca7c84171e074872323e341 src/web_server/response/file_body/tests.rs
|
||||
814d677c56c946d40031cd8228fc3c52061ad0b76fa5aa9d53063d265f82e3d8 src/web_server/response/file.rs
|
||||
9197a21a6b22da430e26bda2d1c899dcb64ae615069458f75547d4754a8044c3 src/web_server/response/file_body/mod.rs
|
||||
e5f5fbe702f66bfcbcbc1d1f3cd3d89bdbb929bb86aed94868a2a06a4b9e59e3 src/web_server/response/file_body/tests.rs
|
||||
c63a5935bf8e101f1813e029dd62da7d073eb598453ee98aafe9ffa6f85157c2 src/web_server/response/headers.rs
|
||||
f826d8816bdb9edab966e10991e45335625ef7d7376169cf6fd1e0e5d01bf868 src/web_server/routing.rs
|
||||
400e1c8aa2fe857d96036a64499fbc3de44c1e3a53811c5b25101fb843359792 src/web_server/security.rs
|
||||
da7c69cd4b26289170d6d89ae3a6d41488fdca3f184cd8f63a160217fa26e49d src/web_server/routing.rs
|
||||
9e584eb4455a18641c2c89f9e9725745c93f32877abf0f0f2fbea9e3d5ef38c3 src/web_server/security.rs
|
||||
b791762b4ab7a43c3be19df84e523faf3dfb4df055f66d02178f93edb60d2204 src/web_server/serve.rs
|
||||
df888adf893d0b6b99348d19fa07bd9c2b8fc0ce7f411d06be7411afb4311fe0 src/web_server/tests.rs
|
||||
642ac020745d963554ab382aa755b8f24d140f5f6b8ea8e7c74da59614f1cfe0 src/web_server/tests.rs
|
||||
f00743af2cf4a5952caef7a1dcf68e7817b5599a252a9973e1c22045517c0b0e tests/fixtures/argon2id.json
|
||||
eca68a07c2b1e45fdb8f512294f5a432db3ae5a6aec8fb200b47f155cd9a31d6 tools/README.md
|
||||
7c30c280d0b0a8bf855eeffab583ca34dc161255f7ef6124148aa979c17c26d3 tools/dev/memory_load.py
|
||||
|
||||
+3
-1
@@ -32,7 +32,9 @@ Method policies allow, block or leave methods unrestricted. A denied method retu
|
||||
## Basic Auth and Tinyauth
|
||||
|
||||
- **Basic Auth:** protect selected Vhosts with configured credentials. Use HTTPS so credentials are not sent over plaintext.
|
||||
- **Tinyauth:** add a verification URL and an HTTPS login URL. RustProxy makes a bounded, body-free authorization request and can pass specifically allowed identity headers upstream. An origin URL can use the service's conventional `/api/auth/nginx` path. Tinyauth has its own timeout and private-backend policy.
|
||||
- **Tinyauth:** add a verification URL and an HTTPS login URL. RustProxy makes a bounded, body-free authorization request and can pass specifically allowed identity headers upstream. An origin URL automatically uses `/api/auth/nginx` (or set that path explicitly). This Nginx auth-request integration sends `X-Original-URL` and `X-Original-Method`, with a validated `X-Forwarded-For` and `X-Real-IP` for Tinyauth IP ACLs. It does **not** send `X-Forwarded-Host` or `X-Forwarded-URI` to the verifier, avoiding the `conflicting auth module headers` rejection introduced in Tinyauth 5.2.0 while keeping compatibility with earlier versions that implement the Nginx endpoint. Tinyauth has its own timeout and private-backend policy.
|
||||
- **Tinyauth error pages (0.34.14):** RustProxy renders built-in, self-contained HTML for verifier failures: `502 Tinyauth connection error` if its HTTP client cannot reach Tinyauth (DNS/TCP/TLS/transport), `504 Tinyauth timeout` if the auth deadline expires, or `502 Tinyauth verification error` for unexpected verifier status or invalid/oversized data. The page always retains the HTTP error status, `Content-Type: text/html; charset=utf-8`, `Cache-Control: private, no-store` and `X-Content-Type-Options: nosniff`. Backend URLs, protocol errors and identity data are not shown to visitors. All of these cases **deny access** to the protected origin. HTTP `401`/`403` and configured login redirects remain unchanged. These auth-specific pages take precedence over custom Vhost/general HTTP error pages so the failure remains distinguishable.
|
||||
- Point the verifier URL **directly** at the private Tinyauth service (for example `http://tinyauth:3000/api/auth/nginx`), rather than routing it through a second public proxy that might inject conflicting headers. Do not disable Tinyauth's header-spoofing protections. Confirm that Tinyauth trusts only the actual RustProxy address/network when enabling Tinyauth IP-based access controls (`TINYAUTH_AUTH_TRUSTEDPROXIES`).
|
||||
- The two authentication integrations should not be enabled simultaneously for the same Vhost. Protected responses bypass unsafe shared caching. Confirm that login redirections and WebSockets behave as expected.
|
||||
|
||||
Do not use a User-Agent blocklist as the primary access control: HTTP clients can forge their User-Agent freely.
|
||||
|
||||
@@ -5,7 +5,7 @@ RustProxy offers built-in integrations and optional helper components. Each has
|
||||
| Integration | Purpose | Setup and limits |
|
||||
|---|---|---|
|
||||
| **Docker agent** | Discover running Docker services and publish generated Vhosts | Install separate agent on Docker host; use Bearer token and TLS certificate pin. [Guide](DOCKER_DISCOVERY.md). |
|
||||
| **Tinyauth** | Delegate authentication for selected Vhosts | Configure verifier URL/login URL, allowed headers and HTTPS. [Access](ACCESS.md). |
|
||||
| **Tinyauth** | Delegate authentication for selected Vhosts | Configure verifier URL/login URL, allowed headers and HTTPS. Failed verifier connections return a fail-closed local 502 page; verifier timeouts return 504. [Access](ACCESS.md). |
|
||||
| **ACME / Certbot** | Issue/renew HTTPS certificates | HTTP-01 or DNS-01 via Cloudflare, OVH or RFC2136; protect credentials. [Certificates](ACME_PROVIDERS.md). |
|
||||
| **Prometheus** | Scrape operational metrics | Separate endpoint/token/CIDR rules. [Monitoring](MONITORING.md). |
|
||||
| **Grafana** | Visualize Prometheus results | Example dashboard under `grafana/README.md`. |
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
# RustProxy documentation
|
||||
|
||||
Practical guides for **RustProxy 0.34.13**. This index and the listed pages are also available in the authenticated panel at **`/docs → Reader`**. The adjacent **API** tab provides the embedded OpenAPI reference. Paths below are links to actual files in the source archive.
|
||||
Practical guides for **RustProxy 0.34.14**. This index and the listed pages are also available in the authenticated panel at **`/docs → Reader`**. The adjacent **API** tab provides the embedded OpenAPI reference. Paths below are links to actual files in the source archive.
|
||||
|
||||
## Getting started
|
||||
|
||||
@@ -22,7 +22,7 @@ Practical guides for **RustProxy 0.34.13**. This index and the listed pages are
|
||||
- [Experimental TLS post-quantum key exchange](TLS_POST_QUANTUM.md) — opt-in X25519MLKEM768, compatibility, rollback and validation.
|
||||
- [TCP/UDP Streams](STREAMS.md) — non-HTTP forwarding and its security boundaries.
|
||||
|
||||
The Vhosts and Docker discovery guides include the shared adaptive request-rate chart scale introduced in 0.34.11. Version 0.34.12 preserves that adaptive range and adds a disabled-by-default X/Y scale display option under **Settings → Appearance → Charts**. Release 0.34.13 adds global HTTP security policies and UI layout improvements, groups the global User-Agent policy under `global_security`, provides consistent section-based GET/PUT APIs, and moves manual GeoIP refresh to `POST /api/config/geoip/update`. See [Dashboard](DASHBOARD.md).
|
||||
The Vhosts and Docker discovery guides include the shared adaptive request-rate chart scale introduced in 0.34.11. Version 0.34.12 preserves that adaptive range and adds a disabled-by-default X/Y scale display option under **Settings → Appearance → Charts**. Release 0.34.13 adds global HTTP security policies and UI layout improvements, groups the global User-Agent policy under `global_security`, provides consistent section-based GET/PUT APIs, and moves manual GeoIP refresh to `POST /api/config/geoip/update`. See [Dashboard](DASHBOARD.md). Release 0.34.14 keeps the Tinyauth Nginx-header compatibility patch, adds fail-closed branded Tinyauth 502/504 error pages, without changing the existing generic 502 page, error-code registry, or other standard error templates. See [Access](ACCESS.md) and [Troubleshooting](TROUBLESHOOTING.md).
|
||||
|
||||
## Integrations and operations
|
||||
|
||||
|
||||
@@ -10,7 +10,10 @@ Start with a reproducible request, its hostname/path and the exact listener. Com
|
||||
| HTTP works, HTTPS does not | Trusted certificate, hostname/SAN coverage, TLS listener, port 443 firewall, certificate assignment and whether restart was needed. |
|
||||
| HTTPS/H2 works but H3 fails | UDP firewall/NAT, H3 toggle on TLS listener, browser QUIC support and actual transport negotiation. |
|
||||
| H2 runs at link speed but H3 is slower | Compare the same origin and client with browser H3 vs H2, keeping TLS/cache/compression consistent. Inspect QUIC loss/cwnd/MTU and VM UDP offload, not only total CPU. |
|
||||
| `502` / `503` / `504` to origin | Backend IP/port, pool eligibility/health, private-address policy, upstream HTTPS verification, protocol `auto`/`h2`, timeout and container/PHP process availability. |
|
||||
| Ordinary `502` / `503` / `504` to origin | Backend IP/port, pool eligibility/health, private-address policy, upstream HTTPS verification, protocol `auto`/`h2`, timeout and container/PHP process availability. A locally generated ordinary 502 has the generic **Bad gateway** page. |
|
||||
| `502 Tinyauth connection error` | The authentication backend cannot be reached. Check Tinyauth process, DNS, verifier URL/port, network firewall, TLS/certificate, private backend allowlist and the RustProxy service journal. Do not route the verification URL back through the protected Vhost. |
|
||||
| `502 Tinyauth verification error` | Tinyauth returned an unexpected status/body or identity headers were too large. Verify `/api/auth/nginx`, proxy header injection and the installed Tinyauth version; check the server journal for details. |
|
||||
| `504 Tinyauth timeout` | The Tinyauth verification deadline was reached. Check service load/latency and `connect_timeout_seconds` / `timeout_seconds` (Vhost Authentication tab). |
|
||||
| WebSocket handshake fails or disconnects | Vhost WebSockets flag, backend Upgrade support, TLS/frontend protocol path, WebSocket idle limits and auth redirect. |
|
||||
| `403` / `405` / `429` | Applicable IP/ACL/country policy, HTTP methods, rate limit, GeoIP availability, Basic/Tinyauth permissions. |
|
||||
| Cache always BYPASS or MISS | Global + Vhost enablement, cookies/login, origin `Cache-Control`, `Set-Cookie`, `Vary`, TTL, size and exclusion rules. |
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ In **Web Server → Edit → Delivery**, static file delivery, dynamic compressi
|
||||
|
||||
A Web Service may enable PHP via a shared PHP-FPM profile or its own configuration. PHP is executed by the FPM service, not RustProxy, and must not be exposed as a raw Internet port. Use dedicated pools for different applications. See [PHP-FPM](PHP_FPM.md).
|
||||
|
||||
Missing static files return **HTTP 404 Not Found**, unreadable/blocked paths **403 Forbidden**, unsupported static methods **405 Method Not Allowed** (with `Allow: GET, HEAD`), and internal failures **500 Internal Server Error**. The built-in Web Server now uses the existing **application-style HTML error pages** for statuses with a bundled template (including 400, 403, 404, 500 and PHP-FPM gateway errors). Other generated error statuses, such as 405, use the shared styled HTML fallback. Neither internal filesystem paths nor `RustProxy: Web Server ...` diagnostics are included in the public body. Details for 5xx filesystem failures remain in server logs.
|
||||
Missing static files return **HTTP 404 Not Found**, unreadable/blocked paths **403 Forbidden**, unsupported static methods **405 Method Not Allowed** (with `Allow: GET, HEAD`), and internal failures **500 Internal Server Error**. The built-in Web Server now uses the existing **application-style HTML error pages** for statuses with a bundled template (including 400, 403, 404, 500 and PHP-FPM gateway errors). Other generated error statuses, such as 405, use the shared styled HTML fallback. The regular built-in 502 is styled with RustProxy branding; auth-specific Tinyauth failure pages have their own wording and are served before any origin application is accessed. Neither internal filesystem paths nor `RustProxy: Web Server ...` diagnostics are included in the public body. Details for 5xx filesystem failures remain in server logs.
|
||||
|
||||
These generated HTML responses retain the actual HTTP status, `Content-Type: text/html; charset=utf-8`, `X-Content-Type-Options: nosniff` and `Cache-Control: no-store`; `HEAD` preserves the matching `Content-Length` but sends no body. Explicit application/origin responses are still passed through without forced replacement, subject to the Vhost error interception options below.
|
||||
|
||||
|
||||
@@ -6868,9 +6868,9 @@
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "browser",
|
||||
"title": "RustProxy 0.34.13 - Operations",
|
||||
"title": "RustProxy 0.34.14 - Operations",
|
||||
"uid": "rustproxy-0170",
|
||||
"version": 7,
|
||||
"weekStart": "",
|
||||
"description": "RustProxy 0.34.13 Prometheus operations dashboard: traffic and errors, vhosts and backends, Docker discovery, cache capacity and pressure, process and system diagnostics, HTTP/2, HTTP/3, TLS, WebSockets, Layer-4 streams, log sinks, Web Server and PHP-FPM. Some metrics are optional depending on exporter collector settings and enabled services."
|
||||
"description": "RustProxy 0.34.14 Prometheus operations dashboard: traffic and errors, vhosts and backends, Docker discovery, cache capacity and pressure, process and system diagnostics, HTTP/2, HTTP/3, TLS, WebSockets, Layer-4 streams, log sinks, Web Server and PHP-FPM. Some metrics are optional depending on exporter collector settings and enabled services."
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "RustProxy Administration API",
|
||||
"version": "0.34.13",
|
||||
"version": "0.34.14",
|
||||
"description": "Administration API for the active panel origin. Sign in through the panel; the same-origin HttpOnly cookie authenticates all private operations. Mutations also require the exact Origin, X-RustProxy-Request: 1 and a session-bound X-CSRF-Token. Loopback HTTP is the default; Settings can enable HTTPS before using a non-loopback administration bind. This document contains no live configuration or credentials. Object schemas marked extensible are summaries: full configuration validation is authoritative in Rust. The API also permits explicitly scoped GeneralApiBearer tokens on a narrow route allowlist, with RO/RW and source CIDR checks; API-token management and Prometheus-token management are browser-session-only."
|
||||
},
|
||||
"servers": [
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>502 - Tinyauth connection error - RustProxy</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 12vh auto;
|
||||
padding: 24px;
|
||||
max-width: 620px;
|
||||
background: #131615;
|
||||
color: #e5e9e6;
|
||||
font: 15px/1.6 system-ui, sans-serif
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
margin: 0 0 8px
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
color: #b9c3bc
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<h1>502 - Tinyauth connection error</h1>
|
||||
<p>Unable to connect to the Tinyauth authentication service.</p>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,37 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>504 - Tinyauth timeout - RustProxy</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 12vh auto;
|
||||
padding: 24px;
|
||||
max-width: 620px;
|
||||
background: #131615;
|
||||
color: #e5e9e6;
|
||||
font: 15px/1.6 system-ui, sans-serif
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
margin: 0 0 8px
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
color: #b9c3bc
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<h1>504 - Tinyauth timeout</h1>
|
||||
<p>The Tinyauth authentication service did not respond in time.</p>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,37 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>502 - Tinyauth verification error - RustProxy</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 12vh auto;
|
||||
padding: 24px;
|
||||
max-width: 620px;
|
||||
background: #131615;
|
||||
color: #e5e9e6;
|
||||
font: 15px/1.6 system-ui, sans-serif
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
margin: 0 0 8px
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
color: #b9c3bc
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<h1>502 - Tinyauth verification error</h1>
|
||||
<p>The Tinyauth authentication service returned an invalid response.</p>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
+16
-1
@@ -86,12 +86,27 @@ mod tests {
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"500 - Internal server error",
|
||||
),
|
||||
(StatusCode::BAD_GATEWAY, "502 - Bad gateway"),
|
||||
] {
|
||||
let page = builtin_gateway_error(code).unwrap();
|
||||
assert!(page.contains(label));
|
||||
assert!(page.contains("background: #131615"));
|
||||
}
|
||||
let gateway_502 = builtin_gateway_error(StatusCode::BAD_GATEWAY).unwrap();
|
||||
assert!(gateway_502.contains("<h1>502 - Bad gateway</h1>"));
|
||||
assert!(gateway_502.contains("The upstream service returned an invalid response."));
|
||||
assert!(gateway_502.contains("RustProxy"));
|
||||
assert!(gateway_502.contains("#131615"));
|
||||
assert!(!gateway_502.contains("Tinyauth"));
|
||||
// The standard HTTP error registry and its stock pages predate the
|
||||
// Tinyauth-specific diagnostic pages and must remain unchanged.
|
||||
assert_eq!(
|
||||
ERROR_CODES,
|
||||
[400, 401, 403, 404, 408, 413, 429, 500, 502, 503, 504]
|
||||
);
|
||||
assert_eq!(
|
||||
BUILTIN_ERROR_CODES,
|
||||
[400, 401, 403, 404, 408, 410, 413, 429, 500, 502, 503, 504]
|
||||
);
|
||||
assert!(builtin_gateway_error(StatusCode::OK).is_none());
|
||||
assert!(builtin_application_page(StatusCode::OK).contains("200 - OK"));
|
||||
assert!(builtin_application_page(StatusCode::CREATED).contains("background: #131615"));
|
||||
|
||||
+101
-23
@@ -63,6 +63,51 @@ pub struct Compiled {
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct AuthenticationFailure;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum CheckError {
|
||||
Connection(anyhow::Error),
|
||||
InvalidResponse(anyhow::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum GatewayFailure {
|
||||
Connection,
|
||||
Timeout,
|
||||
Verification,
|
||||
}
|
||||
|
||||
fn gateway_failure(kind: GatewayFailure) -> Response {
|
||||
let (status, html) = match kind {
|
||||
GatewayFailure::Connection => (
|
||||
StatusCode::BAD_GATEWAY,
|
||||
include_str!("../admin/web/error_tinyauth_connection.html"),
|
||||
),
|
||||
GatewayFailure::Timeout => (
|
||||
StatusCode::GATEWAY_TIMEOUT,
|
||||
include_str!("../admin/web/error_tinyauth_timeout.html"),
|
||||
),
|
||||
GatewayFailure::Verification => (
|
||||
StatusCode::BAD_GATEWAY,
|
||||
include_str!("../admin/web/error_tinyauth_verification.html"),
|
||||
),
|
||||
};
|
||||
let mut response = (status, html).into_response();
|
||||
response.headers_mut().insert(
|
||||
"content-type",
|
||||
HeaderValue::from_static("text/html; charset=utf-8"),
|
||||
);
|
||||
response.headers_mut().insert(
|
||||
"cache-control",
|
||||
HeaderValue::from_static("private, no-store"),
|
||||
);
|
||||
response.headers_mut().insert(
|
||||
"x-content-type-options",
|
||||
HeaderValue::from_static("nosniff"),
|
||||
);
|
||||
response.extensions_mut().insert(AuthenticationFailure);
|
||||
response
|
||||
}
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Identity {
|
||||
headers: HeaderMap,
|
||||
@@ -220,6 +265,31 @@ fn failure(status: StatusCode) -> Response {
|
||||
response.extensions_mut().insert(AuthenticationFailure);
|
||||
response
|
||||
}
|
||||
|
||||
fn apply_nginx_auth_context(
|
||||
headers: &mut HeaderMap,
|
||||
method: &Method,
|
||||
context: &forwarding::Context,
|
||||
) -> Result<()> {
|
||||
context.apply(headers);
|
||||
|
||||
let non_nginx_headers: Vec<_> = headers
|
||||
.keys()
|
||||
.filter(|name| {
|
||||
name.as_str() == "forwarded"
|
||||
|| (name.as_str().starts_with("x-forwarded-") && name.as_str() != "x-forwarded-for")
|
||||
})
|
||||
.cloned()
|
||||
.collect();
|
||||
for name in non_nginx_headers {
|
||||
headers.remove(name);
|
||||
}
|
||||
|
||||
headers.insert("x-original-url", context.original_url.parse()?);
|
||||
headers.insert("x-original-method", method.as_str().parse()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl Compiled {
|
||||
pub fn strip_identity(&self, headers: &mut HeaderMap) {
|
||||
let names: Vec<_> = headers
|
||||
@@ -290,11 +360,18 @@ impl Compiled {
|
||||
};
|
||||
let (status, headers) = match result {
|
||||
Ok(Ok(value)) => value,
|
||||
Ok(Err(error)) => {
|
||||
tracing::debug!(%error,"Tinyauth verification failed");
|
||||
return Err(failure(StatusCode::BAD_GATEWAY));
|
||||
Ok(Err(CheckError::Connection(error))) => {
|
||||
tracing::warn!(%error, "Tinyauth backend connection failed");
|
||||
return Err(gateway_failure(GatewayFailure::Connection));
|
||||
}
|
||||
Ok(Err(CheckError::InvalidResponse(error))) => {
|
||||
tracing::warn!(%error, "Tinyauth returned an invalid verification response");
|
||||
return Err(gateway_failure(GatewayFailure::Verification));
|
||||
}
|
||||
Err(_) => {
|
||||
tracing::warn!("Tinyauth verification timed out");
|
||||
return Err(gateway_failure(GatewayFailure::Timeout));
|
||||
}
|
||||
Err(_) => return Err(failure(StatusCode::GATEWAY_TIMEOUT)),
|
||||
};
|
||||
if status.is_success() {
|
||||
let mut identity = Identity::default();
|
||||
@@ -303,7 +380,8 @@ impl Compiled {
|
||||
for value in headers.get_all(name) {
|
||||
size += value.as_bytes().len();
|
||||
if size > 8192 {
|
||||
return Err(failure(StatusCode::BAD_GATEWAY));
|
||||
tracing::warn!("Tinyauth identity headers exceed the configured limit");
|
||||
return Err(gateway_failure(GatewayFailure::Verification));
|
||||
}
|
||||
identity.headers.append(name.clone(), value.clone());
|
||||
}
|
||||
@@ -323,24 +401,26 @@ impl Compiled {
|
||||
return Err(response);
|
||||
}
|
||||
}
|
||||
Err(failure(if status == StatusCode::FORBIDDEN {
|
||||
StatusCode::FORBIDDEN
|
||||
} else if status == StatusCode::UNAUTHORIZED {
|
||||
StatusCode::UNAUTHORIZED
|
||||
} else {
|
||||
StatusCode::BAD_GATEWAY
|
||||
}))
|
||||
if status == StatusCode::FORBIDDEN || status == StatusCode::UNAUTHORIZED {
|
||||
return Err(failure(status));
|
||||
}
|
||||
tracing::warn!(
|
||||
status = status.as_u16(),
|
||||
"Tinyauth returned an unexpected HTTP status"
|
||||
);
|
||||
Err(gateway_failure(GatewayFailure::Verification))
|
||||
}
|
||||
async fn check(
|
||||
&self,
|
||||
incoming: &HeaderMap,
|
||||
method: &Method,
|
||||
context: &forwarding::Context,
|
||||
) -> Result<(StatusCode, HeaderMap)> {
|
||||
) -> std::result::Result<(StatusCode, HeaderMap), CheckError> {
|
||||
let mut request = Request::builder()
|
||||
.method(Method::GET)
|
||||
.uri(self.uri.clone())
|
||||
.body(Body::empty())?;
|
||||
.body(Body::empty())
|
||||
.map_err(|error| CheckError::InvalidResponse(error.into()))?;
|
||||
for name in &self.request_headers {
|
||||
for value in incoming.get_all(name) {
|
||||
request.headers_mut().append(name.clone(), value.clone());
|
||||
@@ -349,27 +429,25 @@ impl Compiled {
|
||||
crate::proxy::headers::strip_hop_by_hop(request.headers_mut());
|
||||
crate::proxy::headers::strip_admin_cookie(request.headers_mut());
|
||||
self.strip_identity(request.headers_mut());
|
||||
context.apply(request.headers_mut());
|
||||
apply_nginx_auth_context(request.headers_mut(), method, context)
|
||||
.map_err(CheckError::InvalidResponse)?;
|
||||
request
|
||||
.headers_mut()
|
||||
.insert("host", self.backend.host_header.clone());
|
||||
request
|
||||
.headers_mut()
|
||||
.insert("x-original-url", context.original_url.parse()?);
|
||||
request
|
||||
.headers_mut()
|
||||
.insert("x-original-method", method.as_str().parse()?);
|
||||
let response = self
|
||||
.backend
|
||||
.client
|
||||
.request(request)
|
||||
.await
|
||||
.context("Tinyauth request failed")?;
|
||||
.context("Tinyauth request failed")
|
||||
.map_err(CheckError::Connection)?;
|
||||
let (parts, body) = response.into_parts();
|
||||
Limited::new(body, 16 * 1024)
|
||||
.collect()
|
||||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Tinyauth response body: {e}"))?;
|
||||
.map_err(|error| {
|
||||
CheckError::InvalidResponse(anyhow::anyhow!("Tinyauth response body: {error}"))
|
||||
})?;
|
||||
Ok((parts.status, parts.headers))
|
||||
}
|
||||
}
|
||||
|
||||
+202
-2
@@ -9,8 +9,8 @@ mod tests {
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
fn compiled() -> Compiled {
|
||||
settings()
|
||||
fn compile_settings(settings: Settings) -> Compiled {
|
||||
settings
|
||||
.compile(
|
||||
&ValidationPolicy {
|
||||
proxy_addr: "127.0.0.1:8080".parse().unwrap(),
|
||||
@@ -24,6 +24,23 @@ mod tests {
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
}
|
||||
fn compiled() -> Compiled {
|
||||
compile_settings(settings())
|
||||
}
|
||||
fn request_context(incoming: &HeaderMap) -> forwarding::Context {
|
||||
forwarding::Settings::default()
|
||||
.compile()
|
||||
.unwrap()
|
||||
.context(
|
||||
incoming,
|
||||
"192.0.2.5:34567".parse().unwrap(),
|
||||
"10.0.0.1:443".parse().unwrap(),
|
||||
true,
|
||||
&"app.example:443".parse().unwrap(),
|
||||
&"/private?next=%2Fhome".parse().unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
#[test]
|
||||
fn origin_adds_nginx_endpoint() {
|
||||
assert_eq!(
|
||||
@@ -32,6 +49,57 @@ mod tests {
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn nginx_auth_context_has_no_conflicting_forward_auth_headers() {
|
||||
let context = request_context(&HeaderMap::new());
|
||||
let mut headers = HeaderMap::new();
|
||||
apply_nginx_auth_context(&mut headers, &Method::POST, &context).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
headers["x-original-url"],
|
||||
"https://app.example:443/private?next=%2Fhome"
|
||||
);
|
||||
assert_eq!(headers["x-original-method"], "POST");
|
||||
assert_eq!(headers["x-forwarded-for"], "192.0.2.5");
|
||||
assert_eq!(headers["x-real-ip"], "192.0.2.5");
|
||||
for name in [
|
||||
"x-forwarded-host",
|
||||
"x-forwarded-uri",
|
||||
"x-forwarded-proto",
|
||||
"x-forwarded-port",
|
||||
"forwarded",
|
||||
] {
|
||||
assert!(!headers.contains_key(name), "{name}");
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn nginx_auth_context_does_not_forward_spoofed_client_metadata() {
|
||||
let mut headers = HeaderMap::new();
|
||||
for (name, value) in [
|
||||
("x-original-url", "https://evil.example/"),
|
||||
("x-original-method", "DELETE"),
|
||||
("x-forwarded-host", "evil.example"),
|
||||
("x-forwarded-uri", "/admin"),
|
||||
("x-forwarded-for", "203.0.113.1"),
|
||||
("x-real-ip", "203.0.113.1"),
|
||||
("forwarded", "for=203.0.113.1"),
|
||||
] {
|
||||
headers.insert(name, value.parse().unwrap());
|
||||
}
|
||||
let context = request_context(&headers);
|
||||
apply_nginx_auth_context(&mut headers, &Method::GET, &context).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
headers["x-original-url"],
|
||||
"https://app.example:443/private?next=%2Fhome"
|
||||
);
|
||||
assert_eq!(headers["x-original-method"], "GET");
|
||||
assert_eq!(headers["x-forwarded-for"], "192.0.2.5");
|
||||
assert_eq!(headers["x-real-ip"], "192.0.2.5");
|
||||
assert!(!headers.contains_key("x-forwarded-host"));
|
||||
assert!(!headers.contains_key("x-forwarded-uri"));
|
||||
assert!(!headers.contains_key("forwarded"));
|
||||
}
|
||||
#[test]
|
||||
fn rejects_transport_header_injection_and_unsafe_urls() {
|
||||
for name in [
|
||||
"host",
|
||||
@@ -118,4 +186,136 @@ mod tests {
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn tinyauth_gateway_pages_are_distinct_and_fail_closed() {
|
||||
use http_body_util::BodyExt;
|
||||
|
||||
for (kind, status, text) in [
|
||||
(
|
||||
GatewayFailure::Connection,
|
||||
StatusCode::BAD_GATEWAY,
|
||||
"Tinyauth connection error",
|
||||
),
|
||||
(
|
||||
GatewayFailure::Verification,
|
||||
StatusCode::BAD_GATEWAY,
|
||||
"Tinyauth verification error",
|
||||
),
|
||||
(
|
||||
GatewayFailure::Timeout,
|
||||
StatusCode::GATEWAY_TIMEOUT,
|
||||
"Tinyauth timeout",
|
||||
),
|
||||
] {
|
||||
let response = gateway_failure(kind);
|
||||
assert_eq!(response.status(), status);
|
||||
assert_eq!(
|
||||
response.headers()["content-type"],
|
||||
"text/html; charset=utf-8"
|
||||
);
|
||||
assert_eq!(response.headers()["cache-control"], "private, no-store");
|
||||
assert_eq!(response.headers()["x-content-type-options"], "nosniff");
|
||||
assert!(response
|
||||
.extensions()
|
||||
.get::<AuthenticationFailure>()
|
||||
.is_some());
|
||||
let body = response.into_body().collect().await.unwrap().to_bytes();
|
||||
let html = std::str::from_utf8(&body).unwrap();
|
||||
assert!(html.contains(text));
|
||||
assert!(html.contains("Access") && html.contains("protected"));
|
||||
assert!(html.contains("<style>"));
|
||||
assert!(!html.contains("<script") && !html.contains("href=\"http"));
|
||||
assert!(!html.contains("127.0.0.1") && !html.contains("/api/auth/nginx"));
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn unreachable_tinyauth_returns_branded_connection_error() {
|
||||
use http_body_util::BodyExt;
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let address = listener.local_addr().unwrap();
|
||||
drop(listener);
|
||||
let mut config = settings();
|
||||
config.url = format!("http://{address}");
|
||||
config.connect_timeout_seconds = 1;
|
||||
config.timeout_seconds = 2;
|
||||
let auth = compile_settings(config);
|
||||
let headers = HeaderMap::new();
|
||||
let response = auth
|
||||
.authorize(
|
||||
&headers,
|
||||
&Method::GET,
|
||||
&request_context(&headers),
|
||||
&tokio_util::sync::CancellationToken::new(),
|
||||
)
|
||||
.await
|
||||
.unwrap_err();
|
||||
assert_eq!(response.status(), StatusCode::BAD_GATEWAY);
|
||||
let body = response.into_body().collect().await.unwrap().to_bytes();
|
||||
let html = std::str::from_utf8(&body).unwrap();
|
||||
assert!(html.contains("Tinyauth connection error"));
|
||||
assert!(!html.contains(&address.to_string()));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn unresponsive_tinyauth_returns_branded_timeout() {
|
||||
use http_body_util::BodyExt;
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let mut config = settings();
|
||||
config.url = format!("http://{}", listener.local_addr().unwrap());
|
||||
config.connect_timeout_seconds = 1;
|
||||
config.timeout_seconds = 1;
|
||||
let auth = compile_settings(config);
|
||||
let headers = HeaderMap::new();
|
||||
let response = auth
|
||||
.authorize(
|
||||
&headers,
|
||||
&Method::GET,
|
||||
&request_context(&headers),
|
||||
&tokio_util::sync::CancellationToken::new(),
|
||||
)
|
||||
.await
|
||||
.unwrap_err();
|
||||
assert_eq!(response.status(), StatusCode::GATEWAY_TIMEOUT);
|
||||
assert!(
|
||||
std::str::from_utf8(&response.into_body().collect().await.unwrap().to_bytes())
|
||||
.unwrap()
|
||||
.contains("Tinyauth timeout")
|
||||
);
|
||||
drop(listener);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn tinyauth_http_503_is_not_misdiagnosed_as_connection_error() {
|
||||
use http_body_util::BodyExt;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let mut config = settings();
|
||||
config.url = format!("http://{}", listener.local_addr().unwrap());
|
||||
let server = tokio::spawn(async move {
|
||||
let (mut socket, _) = listener.accept().await.unwrap();
|
||||
let mut request = [0_u8; 4096];
|
||||
let read = socket.read(&mut request).await.unwrap();
|
||||
assert!(read > 0, "auth request must be sent to Tinyauth");
|
||||
socket.write_all(b"HTTP/1.1 503 Service Unavailable\r\nContent-Length: 0\r\nConnection: close\r\n\r\n").await.unwrap();
|
||||
});
|
||||
let auth = compile_settings(config);
|
||||
let headers = HeaderMap::new();
|
||||
let response = auth
|
||||
.authorize(
|
||||
&headers,
|
||||
&Method::GET,
|
||||
&request_context(&headers),
|
||||
&tokio_util::sync::CancellationToken::new(),
|
||||
)
|
||||
.await
|
||||
.unwrap_err();
|
||||
server.await.unwrap();
|
||||
assert_eq!(response.status(), StatusCode::BAD_GATEWAY);
|
||||
let body = response.into_body().collect().await.unwrap().to_bytes();
|
||||
assert!(std::str::from_utf8(&body)
|
||||
.unwrap()
|
||||
.contains("Tinyauth verification error"));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user