fatedier

Stars and mentions

Last 30 days, Oct 4 – Nov 2

GitHub stars594
mentions5
019385776Oct 4Oct 18Nov 2
UTC days · repositories fatedier owns3 repositories

Package downloads

No package download history available yet.

Top repositories

fatedier’s repositories ranked by new forks, as on trending.

Loading

Contributes to

Repositories outside fatedier’s account where fatedier opened or reviewed pull requests in the past 365 days.

Who noticed fatedier

Everyone who starred or forked fatedier’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

5posts
Nov 30 posts
  1. Measuring Throughput When the Subprocess Owns the Socket: A TCP Relay Pattern for Tauri Apps If you have ever wanted a traffic graph for a tunnel client, you know the awkward part: the client usually owns the socket. You cannot wrap it, you cannot ask it, and its status endpoint is often a step-function of "connected" or not. When I was building MoonProxy — a cross-platform GUI desktop client for FRP — I hit exactly this. frpc exposes an /api/status endpoint, and it is genuinely useful: it tells you whether the tunnel is up. What it does not expose is a single byte counter. Yet the whole point of a tunnel dashboard is answering "how much data is moving right now?" This is a writeup of the pattern I landed on, because it generalizes well beyond FRP. The constraint The naive approach is to watch the process's network usage from the outside. On Linux that is /proc/<pid>/net/dev; on macOS and Windows it is a platform-specific call. All three have the same two problems: 1. They report traffic for the whole process, with no way to attribute bytes to a specific tunnel. 2. They report host-level interface counters, which include every other program on the machine. For a desktop app whose entire purpose is to show you per-tunnel traffic, neither is acceptable. The user has five tunnels and wants to see them individually. The trick: be the middleman frpc's local proxy config points at a localIP:localPort where your service is listening. That address is just a string in a TOML file. If you own the process that writes that file, you can point it somewhere else. So instead of: frpc ──────────────▶ 127.0.0.1:8080 (your service) you get: frpc ──────▶ 127.0.0.1:53912 ──────▶ 127.0.0.1:8080 (your service) (MoonProxy relay) (your service) MoonProxy opens a listener on an ephemeral port, rewrites localIP/localPort in the proxy config to point at it, and copies bytes in both directions while counting them. The relay is a plain TCP proxy. It is not a protocol-aware proxy, it does not parse HTTP, and it does not care what is on the other end. Counting bytes without copy_bidirectional Tokio has tokio::io::copy_bidirectional, which is exactly the wrong tool here. It is efficient, it is correct, and it returns the total bytes moved in each direction at the end — but only at the end. For a live dashboard you want running totals you can sample at any instant. The obvious substitute, tokio::io::copy, returns bytes copied too, but only when the stream closes. So the counter has to live somewhere that outlives the call. I used a pair of atomic counters incremented inside the copy loop: /// Single-direction copy: read, write, immediately accumulate the counter. /// Equivalent to `tokio::io::copy` but with a live counter. async fn copy_one_way<R, W>( rd: &mut R, wr: &mut W, counter: &AtomicU64, ) -> std::io::Result<u64> where R: tokio::io::AsyncRead + Unpin + ?Sized, W: tokio::io::AsyncWrite + Unpin + ?Sized, { use tokio::io::{AsyncReadExt, AsyncWriteExt}; let mut buf = vec![u8; 8 * 1024]; let mut total = 0u64; loop { let n = rd.read(&mut buf).await?; if n == 0 { return Ok(total); } wr.write_all(&buf[..n]).await?; total += n as u64; counter.fetch_add(n as u64, Ordering::Relaxed); } } fetch_add with Relaxed ordering is the right choice here. The counters are pure statistics — nobody reads them to establish a happens-before relationship with other memory — so paying for SeqCst fencing on every 8 KB chunk would be pure waste. Running two directions concurrently copy_bidirectional runs both directions at once and cancels whichever finishes first. Reproducing that with tokio::select! is straightforward: async fn copy_bidirectional_counted<R1, W1, R2, W2>( user_rd: &mut R1, frpc_wr: &mut W1, in_counter: &AtomicU64, frpc_rd: &mut R2, user_wr: &mut W2, out_counter: &AtomicU64, ) -> (u64, u64) where /* ... */ { let in_task = copy_one_way(user_rd, frpc_wr, in_counter); let out_task = copy_one_way(frpc_rd, user_wr, out_counter); tokio::pin!(in_task); tokio::pin!(out_task); let mut in_bytes = 0u64; let mut out_bytes = 0u64; loop { tokio::select! { res = &mut in_task => { if let Ok(n) = res { in_bytes += n; } break; } res = &mut out_task => { if let Ok(n) = res { out_bytes += n; } break; } } } (in_bytes, out_bytes) } The tokio::pin! calls matter: without pinning, the two futures are dropped at the end of the select! arm and the surviving copy task is cancelled mid-stream. Note the direction convention. I deliberately count in terms of the end user's perspective rather than the process's: - user_conn → frpc_conn = the user's service uploading = in (up) - frpc_conn → user_conn = the user's service downloading = out (down) Getting this backwards is the classic mistake in this kind of tool. A user watching their NAS upload a backup should see the up arrow move, not the down arrow. Connection counting with an RAII guard Counting open connections is where an early-return bug really bites. Every path out of the connection handler has to decrement, and there are a lot of them — a failed TcpStream::connect, a read error, a write error, a panic in the copy loop. Rather than hand-decrementing at each exit, use a guard whose Drop does it: /// Connection-count RAII guard: +1 on construction, -1 on drop, /// so every exit path (early return, error, panic) stays balanced. struct ConnGuard<'a>(&'a AtomicI64); impl ConnGuard<'_> { fn new(c: &AtomicI64) -> Self { c.fetch_add(1, Ordering::Relaxed); Self(c) } } impl Drop for ConnGuard<'_> { fn drop(&mut self) { self.0.fetch_sub(1, Ordering::Relaxed); } } Then the handler body is short enough to audit at a glance: async fn handle_relay_conn(mut frpc_conn: TcpStream, entry: Arc<RelayEntry>) { let mut user_conn = match TcpStream::connect(&entry.upstream).await { Ok(s) => s, Err(_) => return, }; let _guard = ConnGuard::new(&entry.connections); let (mut frpc_rd, mut frpc_wr) = frpc_conn.split(); let (mut user_rd, mut user_wr) = user_conn.split(); copy_bidirectional_counted( &mut user_rd, &mut frpc_wr, &entry.in_bytes, &mut frpc_rd, &mut user_wr, &entry.out_bytes, ).await; } The guard is declared after the connect succeeds, which is important: a failed connection never became a connection. Deriving a rate from a cumulative counter The counters are monotonic totals. The UI wants bytes per second. There are two ways to get there, and the difference matters. Bad: sample the counter, and treat the delta as the rate. This produces a value that is really "bytes in the last interval," and it aliases badly — a single 2 MB chunk arriving between two samples reads as either 2 MB/s or 0 B/s depending entirely on where the sampling boundary lands. Better: keep the previous sample and difference it explicitly. // Swap-and-difference: the previous value is read and replaced atomically. let last_in = state.last_in_bytes.swap(total_in, Ordering::Relaxed); let last_out = state.last_out_bytes.swap(total_out, Ordering::Relaxed); let in_rate = total_in.saturating_sub(last_in); let out_rate = total_out.saturating_sub(last_out); swap is the important detail. It reads and writes in one atomic operation, so two concurrent samplers can never interleave into a corrupted "last value." saturating_sub handles the reset case (the tunnel restarted and the counter went back to zero) without underflowing into a 17-exabyte "negative" rate. With a 1-second sampling tick, the difference is bytes per second, which keeps the arithmetic in the backend trivially simple and leaves the frontend to do nothing but plot. Wiring it to the frontend The backend samples once per second and emits an event: pub async fn poll_traffic(app: AppHandle, start_gen: u64) { const TICK: Duration = Duration::from_secs(1); loop { tokio::time::sleep(TICK).await; let state = match app.try_state::<crate::frpc_state::FrpcState>() { Some(s) => s, None => break, }; // A new start/stop cycle invalidates this sampler. if state.poll_gen.load(Ordering::Acquire) != start_gen { break; } let payload = { let guard = state.relay.lock().await; match guard.as_ref() { Some(r) => sample(r, &state).await, None => break, } }; let _ = app.emit("frpc://traffic", payload); } } Two details here are easy to get wrong: The generation counter. Without poll_gen, an old sampler keeps running after a new tunnel starts, and you end up with two samplers emitting interleaved traffic events. The frontend would show a sawtooth pattern that looks like a network problem but is actually two samplers fighting. poll_traffic must be spawned, not awaited. It is an infinite loop. Awaiting it inside a #[tauri::command] would hang the command forever and the start button would appear to hang with it. Wrap it: tauri::async_runtime::spawn(poll_traffic(app, gen)); The frontend side is then almost trivial, because the backend already did the differencing: export function handleTrafficPayload(p: TrafficPayload) { totalInBytes.value = p.total_in_bytes; totalOutBytes.value = p.total_out_bytes; const now = Date.now(); const snapshot: TrafficSnapshot = { timestamp: now, in_rate: p.in_rate, out_rate: p.out_rate, connections: p.connections, }; latestTraffic.value = snapshot; // Keep a fixed-size rolling window for the chart. const next = trafficHistory.value.concat(snapshot); if (next.length > WINDOW_SIZE) { next.splice(0, next.length - WINDOW_SIZE); } trafficHistory.value = next; } WINDOW_SIZE is 60, matching the 1-second backend tick — a 60-point rolling window is one minute of history, which is long enough to read a trend and short enough that the chart stays responsive. Rewriting the client's config The last piece is the part that makes the whole trick work: pointing frpc at the relay instead of at the user's service. // Bind an ephemeral port on loopback. let listener = match TcpListener::bind(("127.0.0.1", 0u16)).await { Ok(l) => l, Err(e) => { crate::frpc_state::emit_log(app, "system", format!("中转端口绑定失败,跳过 {name}:{e}")); continue; } }; let relay_port = match listener.local_addr() { Ok(a) => a.port(), Err(_) => continue, }; // Rewrite THIS proxy's localIP/localPort to the relay. match p { ProxyConfig::Tcp { local_ip, local_port, .. } | ProxyConfig::Http { local_ip, local_port, .. } | ProxyConfig::Https { local_ip, local_port, .. } => { *local_ip = "127.0.0.1".to_string(); *local_port = relay_port; } ProxyConfig::Udp { .. } => { /* unreachable: UDP is skipped above */ } } Two deliberate decisions: Loopback only. The relay binds 127.0.0.1, never 0.0.0.0. The relay is an internal implementation detail; exposing it on a routable interface would create a new, unintended entry point into the user's local network. UDP is skipped. The relay is TCP-only because it is implemented as a byte stream. UDP would need a separate, connectionless path. Rather than half-implement it, MoonProxy passes UDP proxies through untouched — they simply do not appear in the traffic graph. Binding to port 0 and asking the OS for an ephemeral port is also worth calling out: it avoids a port collision with a user's actual service, which a fixed port would eventually cause. Cleanup Stopping the tunnel has to tear down the listeners. Because each accept loop owns its TcpListener, aborting the task closes the socket: pub async fn stop_relay(state: &RelayState) { let mut entries = state.entries.lock().await; for (_, entry) in entries.drain(..) { if let Some(h) = entry.accept_task.lock().await.take() { h.abort(); } } } In-flight connections end on their own: their copy loop hits a read or write error when the peer goes away, and the ConnGuard drops on the way out, so the connection count returns to zero without any explicit bookkeeping. What this buys you - Per-tunnel byte counts, attributed exactly, with no host-level guessing - Rates that survive a slow network because they are differenced from cumulative totals - A connection count that is correct on every exit path, including panics - No changes to the tunnel client itself — you only rewrite where it points The pattern is not FRP-specific. Any time a subprocess owns the socket and you want to observe the traffic, you can insert yourself in the middle, count the bytes, and let the subprocess do what it was always going to do. MoonProxy MoonProxy is a free, open-source (MIT) cross-platform GUI desktop client for FRP, built with Tauri v2, Vue 3, and Rust. It bundles the frpc binary, so you do not need to install anything separately. - Repository: MoonProxyHQ/moonproxy-desktop - Homepage: moonproxy.app - Runs on macOS (Apple Silicon and Intel) and Windows x64 If this kind of low-level plumbing is your thing, the source is on GitHub and I am happy to answer questions about the details.

    1 reaction
  2. The True ROI of Switching: What Bootstrapped SaaS Teams Really Save on Developer Tunnels For indie hackers, solopreneurs, and small agency founders, every dollar saved extends the runway. Founders audit their cloud bills closely: Lambda invocations, database sizes, vector store costs. Meanwhile developer tooling SaaS creep goes largely unexamined. Take the humble reverse-proxy tunnel. It is essential for testing webhooks from services like Stripe, GitHub, or Twilio, for sharing local staging builds with clients, and for debugging mobile apps against a local backend. Tunnels have also moved from simple utilities toward usage-metered, multi-tier products. A pricing tracker logged several ngrok packaging and pricing changes during 2026 alone, including the rebranding of bandwidth as “data transfer”, new support add-ons, and changes to included TCP addresses. This article works through what switching tunnels is actually worth, using pricing verified in October 2026. The headline numbers are more nuanced than “$120 versus $60”, and the real savings come from team structure and flat-cost options rather than from a cheaper per-seat sticker price. 1. What Tunnels Actually Cost in 2026 Prices change often, so treat the figures below as a snapshot taken on October 24, 2026. | Option | Verified pricing | Notes | | --- | --- | --- | | ngrok Free | $0 with a $5 one-time credit | 3 online endpoints, 1 GB data transfer out, 20,000 HTTP requests, one dev domain, interstitial page on browser traffic | | ngrok Hobbyist | $10/month, or $8/month billed annually ($96/year) | Single user, $10 monthly usage credit, 10 ngrok-branded domains, no bring-your-own domain | | ngrok Pay-as-you-go | $20/month base | Includes 3 users and $20 usage credit; extra users $5/month each; custom domains billed per active hour | | LocalXpose Pro | $8/month billed annually ($96/year) | HTTP, HTTPS, TCP, TLS, UDP; custom domains; free Starter tier has time limits and an interstitial | | Pinggy Pro | About $2.50–$3 per seat per month ($30–$36/year) | Free tier has 60-minute tunnels with random subdomains | | Cloudflare Tunnel | Free | Zero Trust is free for up to 50 users, then $7/user/month on pay-as-you-go | | Self-hosted (frp, Rathole) on a VPS | Software free; DigitalOcean’s cheapest Droplet is $4/month | A flat server cost shared by the whole team, plus your time | Three details change how you should read the “$120 versus $60” framing: - $120/year is ngrok’s Hobbyist plan billed monthly. Billed annually it is $96. LocalXpose Pro also costs $96/year billed annually, so moving between those two saves nothing. - There is no single “$60 tier”. Lean alternatives range from roughly $30–$36/year (Pinggy) to $0 (Cloudflare Tunnel) to about $48/year for a shared self-hosted server. The $60 figure is best treated as a rough midpoint. - ngrok’s free plan is less restrictive in some ways than commonly believed. ngrok’s docs state the free tier has no endpoint timeouts, and the free plan includes one dev domain that does not change on restart. The real friction is the 1 GB monthly transfer cap, the 20,000-request cap, and the interstitial warning page that ngrok injects in front of HTML browser traffic. 2. The Team Math Per-seat comparisons mislead because ngrok’s team pricing is not per-seat Hobbyist plans. Pay-as-you-go includes three users for a $20 monthly base, then charges $5 per additional user. Here is the base annual cost by team size, excluding usage above included credits: | Team size | ngrok Hobbyist per dev (annual billing) | ngrok Pay-as-you-go | Pinggy Pro (at $3/seat) | Self-hosted VPS ($4/month) | | --- | --- | --- | --- | --- | | Solo | $96 | $240 | $36 | $48 | | 3-person studio | $288 | $240 | $108 | $48 | | 6-person agency | $576 | $420 | $216 | $48 | | 10-person team | $960 | $660 | $360 | $48 | For a 10-person team, moving from ngrok Pay-as-you-go ($660) to a shared self-hosted server ($48) saves about $612 a year. That is real money for a bootstrapped micro-SaaS, but keep it in proportion. A product at $5,000 MRR with a 20% net margin earns about $12,000 in annual profit, so $612 is roughly 5% of it. Put differently, at that margin you would need about $3,060 in new revenue to generate $612 in profit. Team add-ons are where per-seat costs creep up. On ngrok’s pay-as-you-go plan, SSO/RBAC is $10 per user per month, and the governance suite (SCIM, account-wide IP restrictions, audit logs) is another $15 per user per month on top of that. If your team does not need those, you are paying for a platform designed for larger organizations. 3. Anatomy of a Modern Tunneling Stack The Established Paradigm: Convenience at a Premium ngrok popularized the single-command workflow (ngrok http 3000) that gives you an instant public HTTPS URL. It still offers the most polished traffic inspection, and its Traffic Policy features include OAuth, SAML, and OIDC identity checks. Those features are capped on small plans: the free plan covers 3 monthly active users and Hobbyist covers 5. Two limits matter most for bootstrapped teams: - Custom domains. Bringing your own domain is not available on Free or Hobbyist. It starts on Pay-as-you-go at $0.01 per active hour. - Usage credits. On Free and Hobbyist, usage stops when the credit runs out rather than billing overages, according to ngrok’s pricing page. That is predictable for budgeting, but it can interrupt a demo. If the interstitial is your only complaint, there is a no-cost workaround. Clients you control can send an ngrok-skip-browser-warning header with any value to bypass it. The Lean Alternatives 1. Dedicated budget tunnels. - LocalXpose offers HTTP, HTTPS, TCP, TLS, and UDP tunnels, custom domains, wildcard tunnels, and a built-in file server on its $96/year Pro plan. - Pinggy works over plain SSH with no install: ssh -p 443 -R0:localhost:3000 a.pinggy.io. It supports HTTP(S), TCP, UDP, and TLS tunnels, and its free tier has unlimited data transfer but 60-minute tunnels. Persistent subdomains and removal of the time cap require the paid plan. 2. Infrastructure-native tunnels. Cloudflare Tunnel is free and runs through the cloudflared agent. Two modes exist, and they are very different: - Quick tunnels (cloudflared tunnel --url http://localhost:8080) need no account and give you a random trycloudflare.com URL. Cloudflare states they are for testing and development only, carry no SLA, have a hard cap on concurrent requests (returning HTTP 429 when exceeded), and do not support Server-Sent Events. - Named tunnels give you a stable hostname on a domain in Cloudflare and are the supported option for real traffic. For teams already on Cloudflare, this is the most cost-effective route. Zero Trust Access is free up to 50 users, and the $7/user/month pay-as-you-go tier applies beyond that. 3. Open-source, self-hosted proxies. - frp is written in Go and supports TCP, UDP, HTTP, and HTTPS forwarding. It is actively released; v0.68.0 shipped in March 2026. - Rathole is written in Rust and is billed by its maintainers as a lightweight, high-performance alternative to frp, with mandatory per-service tokens and a binary that can be as small as about 500 KiB. Its performance advantages over frp are the project’s own claims. It forwards raw TCP and UDP, so plan on a TLS-terminating proxy such as Caddy or nginx if you want HTTPS hostnames. Check its maintenance cadence before depending on it: its last Docker Hub tag is v0.5.0, updated over two years ago. - zrok is open source under Apache 2.0 and can be self-hosted.Self-hosting is not free. A DigitalOcean Basic Droplet starts at $4/month (512 MiB RAM, 1 vCPU, 500 GiB transfer). Hetzner is usually cheaper at equivalent specs, but it raised cloud prices roughly 30–37% on April 1, 2026, and price trackers also noted availability limits from late June 2026, so check current pricing and stock before planning around it. You May Not Need a Tunnel at All For Stripe specifically, the Stripe CLI can forward webhook events to your local server with no public URL: stripe listen --forward-to localhost:3000/webhook. Stripe also documents that you don’t need to configure a webhook endpoint in the Dashboard for this. If Stripe is your main use case, you can cut one tunnel seat entirely. 4. Calculating True ROI: Time Saved vs. Dollars Spent The standard objection to switching is the switching cost itself: if saving $60 takes three hours of configuration, did you save anything? > Net first-year ROI = annual subscription savings − (migration hours + annual maintenance hours) × hourly engineering cost Using an illustrative $75/hour rate: - A solo dev moving from ngrok Hobbyist annual ($96) to Pinggy Pro ($36) saves $60. That savings is gone after 48 minutes of work. Per-seat switching only makes sense when it costs close to nothing. - A 10-person team saving $612 a year by self-hosting breaks even at about 8 hours of total migration and maintenance time. Maintenance is the hidden variable: patching the VPS, rotating tokens, and handling a tunnel outage during a demo all count. When NOT to Switch - You are days from a launch. Pay for the convenience, ship, and revisit during a quiet iteration cycle. - You need vendor compliance documentation. ngrok’s SOC 2 report is available only through its enterprise sales route, with a stated $10,000 minimum spend, and that applies to invoicing too. If a client contract demands vendor SOC 2 evidence, neither the $120 plan nor most $60 alternatives will satisfy it. Check that requirement before comparing prices. - You rely on advanced traffic inspection or identity-aware policies. ngrok’s strongest features are its inspection and Traffic Policy tooling. Cheaper tools offer fewer of these. When to Switch - You are buying individual plans for a whole team. Ten Hobbyist plans cost $960/year on annual billing. Pay-as-you-go ($660), Pinggy ($360), or a named Cloudflare Tunnel ($0) are all cheaper. - The free-tier ceiling is blocking you. If you keep hitting the 1 GB transfer or 20,000-request limits, that is a signal to move to a plan or tool without those limits. - You need a custom domain. On ngrok that means jumping to Pay-as-you-go, while Cloudflare named tunnels, LocalXpose Pro, and Pinggy Pro all support custom domains. - Your webhook URLs keep changing. This depends on the tool. ngrok’s free plan gives you a stable dev domain, while Pinggy’s free tier and Cloudflare quick tunnels issue random URLs. A stable URL on a lean tool means Pinggy Pro or a named Cloudflare Tunnel. 5. Actionable Playbook: Audit and Optimize Your Tunneling Stack Run this over a single sprint, and avoid doing it during a release crunch. Step 1: Inventory Current Usage - How many tunnel accounts are billed to company cards, and on which plan and billing cycle (monthly versus annual)? - Which features are actually used: custom domains, TCP, OAuth policies, traffic inspection, or just HTTP forwarding? - Does anyone use a tunnel only for Stripe webhooks, which the Stripe CLI can replace? Step 2: Run a Parallel Pilot Do not migrate blind. Pick one non-critical project and run a candidate alongside your current tool, for example Cloudflare’s cloudflared tunnel --url http://localhost:8080 for a quick test or a named tunnel for a stable hostname. Measure: 1. Setup friction: minutes to a working, stable public URL. 2. Reliability: did the tunnel drop during long webhook sessions or database migrations? 3. Developer sentiment: did the team find it clunky or did it fit their terminal workflow? Step 3: Standardize and Centralize Billing Fragmented subscriptions happen when developers expense tools individually. Once you pick a winner, standardize on one team plan or one self-hosted standard. If you choose self-hosting, assign an owner for updates and token rotation, and budget those maintenance hours in your ROI formula from the start. Conclusion Bootstrapped margins are built from many disciplined micro-optimizations, and tunnels are a good example because the savings come from structure, not sticker price. Switching a single seat from one $96 plan to another saves little, but moving a team off individual subscriptions to a shared plan, a free Cloudflare named tunnel, or a small self-hosted server can save hundreds of dollars a year. Whatever you choose, verify the current pricing on the vendor’s own page, because tunnel pricing moved repeatedly in 2026. What developer subscription in your stack do you suspect costs more than the value it delivers? Sources - ngrok pricing (machine-readable) - ngrok free plan limits - ngrok pricing history, PricingSaaS - LocalXpose pricing summary, DevTune - Pinggy vs ngrok, Pinggy - Pinggy free-tier details, FreeTier.co - Cloudflare Quick Tunnels docs - The complete guide to Cloudflare Tunnel, Flavio Copes - Cloudflare Zero Trust pricing, CostBench - Rathole on GitHub - Rathole on Docker Hub - frp on GitHub - frp v0.68.0 release notes via frpmgr - DigitalOcean Droplet pricing - Hetzner Cloud review, Better Stack - VPS Price Tracker, Findstack - Stripe CLI listen command - Best ngrok alternatives for indie hackers 2026, DevToolPicks --- Originally published at instatunnel.my

  3. Need to reach a service behind your router? 🔐 frp uses a public server to forward traffic to private network services. Secure access before exposing endpoints. 🌐 fatedier/frp #RemoteAccess #浇朋友 #蓝朋友 #互关 #fo

    20 views
  4. 家里的测试服务只在局域网能访问?🔐 frp 可通过自有公网服务器转发内网端口,支持 TCP 和 HTTP。开放访问前记得设置权限。🌐 fatedier/frp #RemoteAccess #浇朋友 #蓝朋友 #互关 #fo

    25 views
  5. @akikii__ しょうがないなぁ EC2にfrpをインストールして自作NATを作れば。。。 fatedier/frp

    3 likes · 205 views
Trending awards, every completed day and week
Gold
01st place finishes
Silver
02nd place finishes
Bronze
13rd place finishes
Awarded repositories
1Owned by fatedier now

Repositories

Ordered by gold, then silver, then bronze.

  1. frpBest: 3rd by stars, 561 stars001

Every award

Top-three finishes of these repositories in completed trending days and weeks, newest first.

  1. #3 by starsDaily trending
    561 stars
    frp

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.