release: v1.20.2#351
Merged
Merged
Conversation
LAN/tunnel share fixes plus a siteops.SetSecured consolidation. Tunnel share now decompresses gzip so asset URLs in the HTML actually get rewritten. LAN share forwards X-Forwarded-Port and the nginx vhost template stops overriding it with $server_port, so Ziggy and Symfony URL builders stop emitting http://<lan-ip>:443/... when a site is shared over the LAN. Vite dev URLs and other loopback services (RustFS, Mailpit, ...) are now proxied through the share via a /__lerd_vite__/<port>/ prefix, with active port tracking, WebSocket upgrade routing, and a JSON-escaped-slash pass for the form Inertia.js puts in data-page payloads. Toggling TLS now refreshes any running LAN share and Stripe listener so they re-bind to the new backend port. Under the hood the secure/unsecure flow had three drifting copies (CLI, dashboard, MCP); they now all funnel through siteops.SetSecured, with the post-toggle work (Stripe restart, LAN share rebind) done via daemon HTTP notifications so adding a new step happens in exactly one place.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A
lerd lan:sharefollow-up that fixes the bugs uncovered while sharing a real Laravel + Vite + RustFS site over the LAN.The tunnel share proxy was passing gzipped responses through untouched, so on most frameworks the page loaded but every asset URL still pointed at the local
.testdomain and the share rendered white. The LAN share proxy was settingX-Forwarded-Hostbut notX-Forwarded-Port, so Symfony'sRequest::getSchemeAndHttpHost()and Ziggy's URL helper composed asset URLs out of the proxy's host plus nginx's$server_port=443, leakinghttp://<lan-ip>:443/...into the page. Behind that was an nginx-side bug: every site's vhost didfastcgi_param HTTP_X_FORWARDED_PORT $server_portand unconditionally overwrote whatever the upstream proxy sent. A new shared_forwarded.confmap ($real_forwarded_port) reads the upstream header when present and falls back to$server_portonly when the request was direct, so direct browser access athttps://app.test/keeps working unchanged.Vite dev-server URLs (
http://[::1]:5173/...) and RustFS / S3 / other loopback URLs (http://localhost:9000/...) were also leaking into LAN-shared pages and failing on the client device, including from the JSON-escaped form Inertia.js emits indata-pageattributes (http:\/\/localhost:9000\/...). The share proxy now rewrites those references in HTML/JS/CSS/JSON to a/__lerd_vite__/<port>/prefix and forwards the prefixed paths through to the local loopback service, with active-port tracking so transitive imports past the first hop keep working. Vite HMR's WebSocket upgrade routes to the same listener so hot reload works for the device viewing the share without per-projectvite.config.jschanges.Toggling TLS on or off used to leave running share listeners pointing at the old backend port until a manual restart. And under the hood,
lerd secure/lerd unsecurehad three drifting copies (CLI, dashboard, MCP); MCP was missing both the Stripe listener restart and the LAN share refresh, and any new step added today was at risk of being forgotten in two of the three places. The consolidation landssiteops.SetSecuredas the single source of truth for the TLS toggle flow: every entry-point now calls one function with no per-caller variation, and all post-toggle work (Stripe webhook restart, LAN share rebind) goes through HTTP notifications to the daemon so adding a new step happens in exactly one place.The
Referer-based Vite routing the proxy used briefly was deliberately dropped: the share listens on0.0.0.0, so trusting aRefererfor the target port would let any device on the network craftReferer: http://host/__lerd_vite__/22/anythingand steer the proxy at SSH or the database. Active-port fallback covers every legitimate case anyway.Full prose and per-bullet detail in
docs/changelog.md. Newsiteops.SetSecuredcovered by five unit tests; the share proxy got fifteen new test cases covering gzip handling, the JSON-escaped slash rewriter, CSSurl()terminator, WebSocket upgrade dispatch, active-port poisoning by non-Vite services, and the SSRF guard.