<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: F1</title>
    <description>The latest articles on Forem by F1 (@fengyily).</description>
    <link>https://forem.com/fengyily</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3833474%2Fc8dcd6b8-8ee9-4859-8755-d7c15d374360.png</url>
      <title>Forem: F1</title>
      <link>https://forem.com/fengyily</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/fengyily"/>
    <language>en</language>
    <item>
      <title>I built an open-source tool that lets you access RDP, SSH, and VNC through any browser — no VPN or client apps needed</title>
      <dc:creator>F1</dc:creator>
      <pubDate>Mon, 23 Mar 2026 13:13:21 +0000</pubDate>
      <link>https://forem.com/fengyily/i-built-an-open-source-tool-that-lets-you-access-rdp-ssh-and-vnc-through-any-browser-no-vpn-or-3l0a</link>
      <guid>https://forem.com/fengyily/i-built-an-open-source-tool-that-lets-you-access-rdp-ssh-and-vnc-through-any-browser-no-vpn-or-3l0a</guid>
      <description>&lt;p&gt;Hey，I've been working on &lt;strong&gt;Shield CLI&lt;/strong&gt;, an open-source tool that creates encrypted tunnels to your internal services and makes them accessible directly in the browser.&lt;/p&gt;

&lt;p&gt;The thing that sets it apart from tools like ngrok or frp: it doesn't just expose a port. It actually &lt;strong&gt;renders RDP desktops, VNC sessions, and SSH terminals as HTML5&lt;/strong&gt; in the browser. You don't need an RDP client, a VNC viewer, or even a terminal emulator — everything runs in the browser tab.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highlights:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Written in Go, single binary, runs on macOS/Linux/Windows&lt;/li&gt;
&lt;li&gt;Docker support for easy deployment&lt;/li&gt;
&lt;li&gt;Web UI dashboard to manage your tunnels&lt;/li&gt;
&lt;li&gt;Apache 2.0 license — fully open source&lt;/li&gt;
&lt;li&gt;Encrypted tunnels by default&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzcw3glq2savk5m3s79i.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzcw3glq2savk5m3s79i.gif" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flh4zy5oy97buam6sff5h.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flh4zy5oy97buam6sff5h.gif" alt=" " width="960" height="540"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Use cases I built it for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accessing my home server's desktop remotely without setting up a VPN&lt;/li&gt;
&lt;li&gt;Giving temporary SSH access to someone without sharing keys or VPN configs&lt;/li&gt;
&lt;li&gt;Quick remote support for family members (just send them a link)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's still a relatively young project, so I'd love to hear what features matter most to you.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/fengyily/shield-cli" rel="noopener noreferrer"&gt;https://github.com/fengyily/shield-cli&lt;/a&gt;&lt;/p&gt;

</description>
      <category>network</category>
      <category>opensource</category>
      <category>tooling</category>
      <category>browser</category>
    </item>
    <item>
      <title>I Opened an Intranet RDP Desktop in a Browser with One Command — A Technical Comparison of Shield CLI vs Popular Tunnel Tools</title>
      <dc:creator>F1</dc:creator>
      <pubDate>Thu, 19 Mar 2026 09:58:57 +0000</pubDate>
      <link>https://forem.com/fengyily/i-opened-an-intranet-rdp-desktop-in-a-browser-with-one-command-a-technical-comparison-of-shield-4i97</link>
      <guid>https://forem.com/fengyily/i-opened-an-intranet-rdp-desktop-in-a-browser-with-one-command-a-technical-comparison-of-shield-4i97</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;I've been exploring remote operations solutions recently, needing to expose intranet Windows Remote Desktop and Linux SSH to external collaborators. After trying ngrok, frp, and Cloudflare Tunnel, I discovered Shield CLI — a tool with a fundamentally different approach. I spent some time doing an in-depth comparison and documented the technical details here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  First, the Scenario: Why "Tunneling" Doesn't Equal "Remote Access"
&lt;/h2&gt;

&lt;p&gt;The typical use case for tunnel tools is: you have a local web service running and want to give someone external temporary access. ngrok is practically the standard for this scenario.&lt;/p&gt;

&lt;p&gt;But what if your scenario looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need a client to operate an intranet Windows Remote Desktop (RDP) directly through a browser&lt;/li&gt;
&lt;li&gt;You want to give an outsourced team temporary SSH terminal access without requiring them to install any client software&lt;/li&gt;
&lt;li&gt;A VNC desktop in a demo environment needs a shareable link&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where you'll find that, yes, ngrok can establish a TCP tunnel, but the other party still needs to install an RDP client or configure an SSH tool. &lt;strong&gt;Tunneling solves "network reachability," but not "terminal usability."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Shield CLI's approach: after the tunnel is established, it provides an HTML5 Web terminal directly at the gateway (based on protocol gateways like Apache Guacamole). Users get an HTTPS link — open it in a browser and you have an RDP desktop or SSH terminal.&lt;/p&gt;

&lt;p&gt;This is the fundamental difference in approach between these products. Let's dive into the detailed comparison.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Protocol Support: Who Actually Delivers "Remote Desktop"
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;Shield CLI&lt;/th&gt;
&lt;th&gt;ngrok&lt;/th&gt;
&lt;th&gt;frp&lt;/th&gt;
&lt;th&gt;Cloudflare Tunnel&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTTP/HTTPS&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generic TCP&lt;/td&gt;
&lt;td&gt;✅ (via specific protocols)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (Spectrum)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UDP&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌ (paid)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSH (browser terminal)&lt;/td&gt;
&lt;td&gt;✅ Built-in Web Terminal&lt;/td&gt;
&lt;td&gt;❌ TCP forwarding only&lt;/td&gt;
&lt;td&gt;❌ TCP forwarding only&lt;/td&gt;
&lt;td&gt;✅ (requires Access config)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RDP (browser desktop)&lt;/td&gt;
&lt;td&gt;✅ Built-in Web Desktop&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VNC (browser desktop)&lt;/td&gt;
&lt;td&gt;✅ Built-in Web Desktop&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Telnet&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SFTP file transfer&lt;/td&gt;
&lt;td&gt;✅ (in SSH mode with &lt;code&gt;--enable-sftp&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key difference&lt;/strong&gt;: ngrok and frp perform &lt;strong&gt;L4 port forwarding&lt;/strong&gt; — they map the remote port 3389 to the public internet, but users still need to launch mstsc.exe (Windows Remote Desktop Client) to connect. Shield CLI performs &lt;strong&gt;L7 protocol rendering&lt;/strong&gt; — remote services are rendered directly in the browser via HTML5, with zero client installation.&lt;/p&gt;

&lt;p&gt;Let's look at actual command comparisons. Exposing an intranet Windows machine's RDP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ngrok: establishes the tunnel, but the other party needs an RDP client&lt;/span&gt;
ngrok tcp 3389
&lt;span class="c"&gt;# Output: tcp://0.tcp.ngrok.io:12345&lt;/span&gt;
&lt;span class="c"&gt;# Other party needs to: open Remote Desktop Connection → enter 0.tcp.ngrok.io:12345 → log in&lt;/span&gt;

&lt;span class="c"&gt;# frp: requires deploying an frps server + writing config files&lt;/span&gt;
&lt;span class="c"&gt;# frpc.toml:&lt;/span&gt;
&lt;span class="c"&gt;# [[proxies]]&lt;/span&gt;
&lt;span class="c"&gt;# name = "rdp"&lt;/span&gt;
&lt;span class="c"&gt;# type = "tcp"&lt;/span&gt;
&lt;span class="c"&gt;# localIP = "127.0.0.1"&lt;/span&gt;
&lt;span class="c"&gt;# localPort = 3389&lt;/span&gt;
&lt;span class="c"&gt;# remotePort = 7001&lt;/span&gt;
frpc &lt;span class="nt"&gt;-c&lt;/span&gt; frpc.toml
&lt;span class="c"&gt;# Other party needs to: same as ngrok, must have an RDP client&lt;/span&gt;

&lt;span class="c"&gt;# Shield CLI: one command, open directly in browser&lt;/span&gt;
shield rdp &lt;span class="nt"&gt;--username&lt;/span&gt; admin &lt;span class="nt"&gt;--auth-pass&lt;/span&gt; mypass
&lt;span class="c"&gt;# Output: https://xxxx-yishield.ac.example.com&lt;/span&gt;
&lt;span class="c"&gt;# Other party needs to: click the link, done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same for SSH:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Shield CLI&lt;/span&gt;
shield ssh 10.0.0.5 &lt;span class="nt"&gt;--username&lt;/span&gt; root
&lt;span class="c"&gt;# Web terminal appears directly in browser, supports SFTP file upload/download&lt;/span&gt;

&lt;span class="c"&gt;# ngrok&lt;/span&gt;
ngrok tcp 22
&lt;span class="c"&gt;# Other party needs to: ssh -p 12345 root@0.tcp.ngrok.io&lt;/span&gt;
&lt;span class="c"&gt;# Plus dealing with known_hosts, keys, etc.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. Configuration Complexity: From "One Command" to "A Pile of Config Files"
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Shield CLI's Smart Defaults
&lt;/h3&gt;

&lt;p&gt;Shield CLI's CLI parameter design includes extensive default inference to minimize input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shield ssh                  &lt;span class="c"&gt;# equivalent to 127.0.0.1:22&lt;/span&gt;
shield ssh 2222             &lt;span class="c"&gt;# equivalent to 127.0.0.1:2222 (pure number → port)&lt;/span&gt;
shield ssh 10.0.0.5         &lt;span class="c"&gt;# equivalent to 10.0.0.5:22 (IP → use default port)&lt;/span&gt;
shield ssh 10.0.0.5:2222    &lt;span class="c"&gt;# fully specified&lt;/span&gt;
shield rdp                  &lt;span class="c"&gt;# equivalent to 127.0.0.1:3389&lt;/span&gt;
shield vnc 10.0.0.10:5901   &lt;span class="c"&gt;# fully specified&lt;/span&gt;
shield http 3000            &lt;span class="c"&gt;# equivalent to 127.0.0.1:3000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This logic is implemented in &lt;code&gt;cmd/helpers.go&lt;/code&gt;: pure number → port (uses 127.0.0.1), contains &lt;code&gt;.&lt;/code&gt; or &lt;code&gt;:&lt;/code&gt; → IP or IP:Port, empty → default IP + default port. Each protocol has its own default port (SSH=22, RDP=3389, VNC=5900, HTTP=80, HTTPS=443, Telnet=23).&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration Comparison with frp
&lt;/h3&gt;

&lt;p&gt;frp is the classic self-hosted tunnel solution, but has a higher configuration barrier. Here's a complete SSH forwarding config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# frps.toml (server side — you need a public-facing machine)&lt;/span&gt;
&lt;span class="py"&gt;bindPort&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7000&lt;/span&gt;

&lt;span class="c"&gt;# frpc.toml (client side)&lt;/span&gt;
&lt;span class="py"&gt;serverAddr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"your-server.com"&lt;/span&gt;
&lt;span class="py"&gt;serverPort&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;7000&lt;/span&gt;

&lt;span class="nn"&gt;[[proxies]]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"ssh"&lt;/span&gt;
&lt;span class="py"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"tcp"&lt;/span&gt;
&lt;span class="py"&gt;localIP&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;
&lt;span class="py"&gt;localPort&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;
&lt;span class="py"&gt;remotePort&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This involves: deploying a server, configuring port mappings, managing config files, and maintaining a public server. Shield CLI doesn't require you to manage a server — the public gateway is provided by Shield's infrastructure (similar to ngrok's model), while the CLI side is open source (Apache 2.0).&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration Comparison with ngrok
&lt;/h3&gt;

&lt;p&gt;ngrok's single command is indeed concise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok http 8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But in multi-protocol scenarios (e.g., needing SSH + RDP + an HTTP service simultaneously), ngrok requires a config file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ngrok.yml&lt;/span&gt;
&lt;span class="na"&gt;tunnels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ssh&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;proto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tcp&lt;/span&gt;
    &lt;span class="na"&gt;addr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;22&lt;/span&gt;
  &lt;span class="na"&gt;rdp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;proto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tcp&lt;/span&gt;
    &lt;span class="na"&gt;addr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3389&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;proto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
    &lt;span class="na"&gt;addr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Shield CLI manages multiple services through a Web UI (&lt;code&gt;shield start&lt;/code&gt;), supporting up to 10 saved application configurations. You can dynamically manage connections by clicking Connect/Disconnect in the interface — no config files needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration Comparison with Cloudflare Tunnel
&lt;/h3&gt;

&lt;p&gt;Cloudflare Tunnel has the most complex configuration (but is also the most powerful):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# config.yml&lt;/span&gt;
&lt;span class="na"&gt;tunnel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;your-tunnel-id&lt;/span&gt;
&lt;span class="na"&gt;credentials-file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/root/.cloudflared/your-tunnel-id.json&lt;/span&gt;

&lt;span class="na"&gt;ingress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ssh.example.com&lt;/span&gt;
    &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ssh://localhost:22&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rdp.example.com&lt;/span&gt;
    &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rdp://localhost:3389&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http_status:404&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You also need: Cloudflare account → add domain → create Tunnel → configure DNS → configure Access Policy. For enterprise-grade persistent deployments this is justified, but for "temporarily giving someone remote desktop access," it's using a sledgehammer to crack a nut.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Security Model Comparison
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Credential Storage
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Shield CLI&lt;/th&gt;
&lt;th&gt;ngrok&lt;/th&gt;
&lt;th&gt;frp&lt;/th&gt;
&lt;th&gt;Cloudflare Tunnel&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Credential storage&lt;/td&gt;
&lt;td&gt;AES-256-GCM encrypted local file&lt;/td&gt;
&lt;td&gt;Token stored in plaintext in &lt;code&gt;~/.ngrok2/ngrok.yml&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Token in config file&lt;/td&gt;
&lt;td&gt;JSON file stored in &lt;code&gt;~/.cloudflared/&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Key source&lt;/td&gt;
&lt;td&gt;Machine fingerprint SHA256 (hostname + MAC + Machine ID)&lt;/td&gt;
&lt;td&gt;User account token&lt;/td&gt;
&lt;td&gt;User-defined&lt;/td&gt;
&lt;td&gt;Issued by Cloudflare&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-machine migration&lt;/td&gt;
&lt;td&gt;❌ Encrypted file bound to machine, invalidated after migration&lt;/td&gt;
&lt;td&gt;✅ Token is portable&lt;/td&gt;
&lt;td&gt;✅ Config file is portable&lt;/td&gt;
&lt;td&gt;✅ Credential file is portable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Shield CLI's approach is interesting: it uses the &lt;strong&gt;machine fingerprint&lt;/strong&gt; as the AES-256-GCM encryption key. The fingerprint consists of three parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hostname (&lt;code&gt;os.Hostname()&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;MAC address of the first physical network interface (skipping docker/br-/veth/virbr and other virtual interfaces)&lt;/li&gt;
&lt;li&gt;Platform-level Machine ID (Linux: &lt;code&gt;/etc/machine-id&lt;/code&gt;, macOS: &lt;code&gt;IOPlatformUUID&lt;/code&gt;, Windows: Registry &lt;code&gt;MachineGuid&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The three are concatenated and SHA256 hashed to derive the AES key. This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduced credential leak risk&lt;/strong&gt;: Even if someone copies the &lt;code&gt;~/.shield-cli/.credential&lt;/code&gt; file, it can't be decrypted on another machine (different machine fingerprint)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No "login" required&lt;/strong&gt;: Credentials are automatically generated and registered with the server on first use, with identity bound to the machine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trade-off&lt;/strong&gt;: Switching machines or reinstalling the OS requires &lt;code&gt;shield clean&lt;/code&gt; to reset credentials&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compare this with ngrok's &lt;code&gt;ngrok config add-authtoken &amp;lt;token&amp;gt;&lt;/code&gt; approach — the token is in plaintext and can be copied to another machine and used immediately. Convenient but higher risk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Access Control
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Shield CLI&lt;/th&gt;
&lt;th&gt;ngrok&lt;/th&gt;
&lt;th&gt;frp&lt;/th&gt;
&lt;th&gt;Cloudflare Tunnel&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Public links&lt;/td&gt;
&lt;td&gt;✅ Visible mode (default)&lt;/td&gt;
&lt;td&gt;✅ Public by default&lt;/td&gt;
&lt;td&gt;✅ Public by default&lt;/td&gt;
&lt;td&gt;❌ Requires Access policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authorized access&lt;/td&gt;
&lt;td&gt;🔜 Invisible mode (planned)&lt;/td&gt;
&lt;td&gt;✅ IP whitelist/OAuth (paid)&lt;/td&gt;
&lt;td&gt;✅ Self-implemented&lt;/td&gt;
&lt;td&gt;✅ Access (zero trust)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Link validity&lt;/td&gt;
&lt;td&gt;24-hour API Key auto-refresh&lt;/td&gt;
&lt;td&gt;Free tier: 2 hours/8 hours&lt;/td&gt;
&lt;td&gt;Unlimited (while server runs)&lt;/td&gt;
&lt;td&gt;Unlimited (while Tunnel runs)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Shield CLI currently defaults to Visible mode — the generated HTTPS link is accessible by anyone. However, the server sets a &lt;strong&gt;24-hour validity period&lt;/strong&gt; for each API Key, which auto-refreshes upon expiration. Compared to ngrok's free tier 2-hour limit (adjusted after 2024), Shield's free quota is more generous.&lt;/p&gt;

&lt;p&gt;Cloudflare Tunnel is the strongest on security — you can configure comprehensive zero-trust policies (email verification, SAML SSO, IP restrictions, etc.), but this also means heavier configuration overhead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Password Handling
&lt;/h3&gt;

&lt;p&gt;Shield CLI applies password masking in logs — showing only the first and last 2 characters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connecting to 10.0.0.5:22 with password: my****ss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SSH private keys are passed via the &lt;code&gt;--private-key&lt;/code&gt; parameter as a file path, so key contents are never exposed on the command line. After credentials are transmitted to the server, they are stored in &lt;code&gt;main_app_config&lt;/code&gt; for protocol gateway authentication.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Architecture Comparison: Chisel vs ngrok's Proprietary Protocol
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Shield CLI's Dual-Layer Tunnel Architecture
&lt;/h3&gt;

&lt;p&gt;Shield CLI uses &lt;a href="https://github.com/jpillora/chisel" rel="noopener noreferrer"&gt;Chisel&lt;/a&gt; (a WebSocket-based TCP tunnel library) under the hood. It establishes two tunnels:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────┐                    ┌──────────────┐                    ┌──────────────────┐
│ Intranet Service │ ←── Local Net ──→  │ Shield CLI   │ ←── WebSocket ──→  │ Public Gateway   │
│ RDP/SSH/VNC      │                    │  (chisel     │     (wss://)       │ + Protocol       │
│ 10.0.0.5         │                    │   client)    │                    │   Rendering      │
└──────────────────┘                    └──────────────┘                    │   (Guacamole)    │
                                            │                               └──────────────────┘
                                       Tunnel 1: API Tunnel                        │
                                       (Control channel,               Tunnel 2: Resource Tunnel
                                        persistent)                   (Data channel, on-demand)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;API Tunnel&lt;/strong&gt; (Main Tunnel): Established on first connection, maps the local REST API port to the public network for dynamic management of subsequent resource tunnels. This tunnel is maintained persistently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource Tunnel&lt;/strong&gt;: Each application creates an independent chisel connection on demand, mapping the target service port to the public gateway. Up to 3 concurrent connections.&lt;/p&gt;

&lt;p&gt;The benefit of this design: the API tunnel provides a "control plane," allowing the gateway to dynamically add or remove resource tunnels without requiring manual user intervention.&lt;/p&gt;

&lt;h3&gt;
  
  
  ngrok's Architecture
&lt;/h3&gt;

&lt;p&gt;ngrok uses a proprietary self-developed protocol. The client connects to ngrok's edge servers via TLS, with protocol details undisclosed. The upside is that performance can be optimized to the extreme; the downside is complete dependence on ngrok's infrastructure with no way to audit.&lt;/p&gt;

&lt;h3&gt;
  
  
  frp's Architecture
&lt;/h3&gt;

&lt;p&gt;frp uses a custom binary protocol (or optional KCP/QUIC). Both client and server are open source, so you can fully self-host. However, there's no protocol rendering layer — it only does port forwarding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloudflare Tunnel's Architecture
&lt;/h3&gt;

&lt;p&gt;cloudflared connects to Cloudflare's global edge network via QUIC protocol, automatically using Anycast to select the nearest node. At the infrastructure level, this is the most robust solution (200+ data centers), but all your traffic passes through Cloudflare.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Local Management Experience
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Shield CLI's Web UI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;shield start
&lt;span class="c"&gt;# Browser automatically opens http://localhost:8181&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This launches a local web management interface with features including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Application management&lt;/strong&gt;: Add/edit/delete app configurations (protocol, target IP:Port, credentials, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One-click connect&lt;/strong&gt;: Click the Connect button, tunnel is established in the background, access link pops up on success&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status monitoring&lt;/strong&gt;: Real-time display of each application's connection status (idle / connecting / connected / failed)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistent configuration&lt;/strong&gt;: Up to 10 application configs, AES-256-GCM encrypted storage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dark/Light theme&lt;/strong&gt;: Toggle support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The frontend is pure HTML5 + vanilla JS (~1500 lines), embedded in the binary with no external dependencies. The backend is a standard REST API.&lt;/p&gt;

&lt;h3&gt;
  
  
  ngrok's Management
&lt;/h3&gt;

&lt;p&gt;ngrok's free tier has no local UI. You can view request logs (HTTP tunnels only) via &lt;code&gt;http://localhost:4040&lt;/code&gt;, but you can't manage multiple tunnels. Full management is on the ngrok Dashboard (SaaS), requiring account registration.&lt;/p&gt;

&lt;h3&gt;
  
  
  frp's Management
&lt;/h3&gt;

&lt;p&gt;frp has an optional Dashboard (enabled when launching &lt;code&gt;frps&lt;/code&gt;) for viewing proxy lists and traffic statistics. However, it runs on the server side, not as a local client management interface. The UI is also quite basic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloudflare Tunnel's Management
&lt;/h3&gt;

&lt;p&gt;Managed through the Cloudflare Zero Trust Dashboard (SaaS). The most comprehensive feature set (traffic analytics, access policies, audit logs), but cloud-dependent.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Deployment &amp;amp; Distribution
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Shield CLI&lt;/th&gt;
&lt;th&gt;ngrok&lt;/th&gt;
&lt;th&gt;frp&lt;/th&gt;
&lt;th&gt;Cloudflare Tunnel&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Installation&lt;/td&gt;
&lt;td&gt;Homebrew / Scoop / curl / dpkg / rpm / source build&lt;/td&gt;
&lt;td&gt;Homebrew / apt / choco / snap / official download&lt;/td&gt;
&lt;td&gt;GitHub Release download / source build&lt;/td&gt;
&lt;td&gt;Homebrew / apt / official download&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Binary size&lt;/td&gt;
&lt;td&gt;~15 MB&lt;/td&gt;
&lt;td&gt;~25 MB&lt;/td&gt;
&lt;td&gt;~12 MB (frpc)&lt;/td&gt;
&lt;td&gt;~35 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Platform support&lt;/td&gt;
&lt;td&gt;Linux/macOS/Windows (amd64/arm64/386)&lt;/td&gt;
&lt;td&gt;Linux/macOS/Windows/FreeBSD&lt;/td&gt;
&lt;td&gt;Linux/macOS/Windows/FreeBSD + more&lt;/td&gt;
&lt;td&gt;Linux/macOS/Windows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;China mirror&lt;/td&gt;
&lt;td&gt;✅ jsDelivr CDN mirror&lt;/td&gt;
&lt;td&gt;❌ Requires VPN to download&lt;/td&gt;
&lt;td&gt;✅ GitHub directly accessible in China&lt;/td&gt;
&lt;td&gt;❌ Requires VPN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;License&lt;/td&gt;
&lt;td&gt;Apache 2.0 (CLI side)&lt;/td&gt;
&lt;td&gt;Proprietary&lt;/td&gt;
&lt;td&gt;Apache 2.0 (full)&lt;/td&gt;
&lt;td&gt;Proprietary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted server&lt;/td&gt;
&lt;td&gt;🔜 Planned&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅ Fully supported&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For users in mainland China, Shield CLI provides a jsDelivr CDN mirror for installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://cdn.jsdelivr.net/gh/fengyily/shield-cli@main/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Downloading ngrok and Cloudflare Tunnel in China is often blocked — a real pain point.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Pricing &amp;amp; Limitations
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Shield CLI&lt;/th&gt;
&lt;th&gt;ngrok (Free)&lt;/th&gt;
&lt;th&gt;ngrok (Personal $8/mo)&lt;/th&gt;
&lt;th&gt;frp&lt;/th&gt;
&lt;th&gt;Cloudflare Tunnel&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;$8/month&lt;/td&gt;
&lt;td&gt;Free (server costs for self-hosting)&lt;/td&gt;
&lt;td&gt;Free (domain must be on CF)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tunnel count&lt;/td&gt;
&lt;td&gt;3 concurrent&lt;/td&gt;
&lt;td&gt;1 agent / 1 domain&lt;/td&gt;
&lt;td&gt;2 agents / 1 domain&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Saved configs&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Unlimited config files&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bandwidth limit&lt;/td&gt;
&lt;td&gt;Not stated&lt;/td&gt;
&lt;td&gt;1 GB/month&lt;/td&gt;
&lt;td&gt;1 GB/month&lt;/td&gt;
&lt;td&gt;Depends on server&lt;/td&gt;
&lt;td&gt;Not stated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Connection duration&lt;/td&gt;
&lt;td&gt;24 hours (auto-renewal)&lt;/td&gt;
&lt;td&gt;2 hours (requires reconnect)&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TCP tunnels&lt;/td&gt;
&lt;td&gt;✅ Free&lt;/td&gt;
&lt;td&gt;❌ Paid only&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ (Spectrum, paid)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom domains&lt;/td&gt;
&lt;td&gt;🔜 Planned&lt;/td&gt;
&lt;td&gt;❌ Paid only&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access logs&lt;/td&gt;
&lt;td&gt;Local logs&lt;/td&gt;
&lt;td&gt;Dashboard&lt;/td&gt;
&lt;td&gt;Dashboard&lt;/td&gt;
&lt;td&gt;Dashboard&lt;/td&gt;
&lt;td&gt;Dashboard + analytics&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;An often-overlooked detail: &lt;strong&gt;ngrok's free tier does not support TCP tunnels&lt;/strong&gt;. This means you cannot use ngrok for free to forward SSH (port 22) or RDP (port 3389). Shield CLI's TCP-based protocols (SSH/RDP/VNC/Telnet) are all free to use.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Real-World Usage Comparison
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scenario 1: Demoing an Intranet System to a Client
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Shield CLI: one command, share the link&lt;/span&gt;
shield http 3000
&lt;span class="c"&gt;# → https://abc123-yishield.ac.example.com&lt;/span&gt;
&lt;span class="c"&gt;# Client clicks the link and sees your application directly&lt;/span&gt;

&lt;span class="c"&gt;# ngrok: similar, but free tier links expire in 2 hours&lt;/span&gt;
ngrok http 3000
&lt;span class="c"&gt;# → https://abc123.ngrok-free.app&lt;/span&gt;
&lt;span class="c"&gt;# Client sees an ngrok warning page when visiting (free tier)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ngrok's free tier has an interstitial warning page ("You are about to visit..."), which looks unprofessional during client demos. Shield CLI doesn't have this limitation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 2: Remote Assistance for a Windows Desktop
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Shield CLI: Windows desktop appears directly in browser&lt;/span&gt;
shield rdp 10.0.0.100 &lt;span class="nt"&gt;--username&lt;/span&gt; admin &lt;span class="nt"&gt;--auth-pass&lt;/span&gt; P@ssw0rd
&lt;span class="c"&gt;# → https://xxx-yishield.ac.example.com&lt;/span&gt;
&lt;span class="c"&gt;# The other party operates a full Windows desktop in the browser&lt;/span&gt;

&lt;span class="c"&gt;# Other tools: none can render RDP in a browser&lt;/span&gt;
&lt;span class="c"&gt;# ngrok: ngrok tcp 3389 → other party needs an RDP client&lt;/span&gt;
&lt;span class="c"&gt;# If the other party is on Mac/Linux, they also need to install Microsoft Remote Desktop or Remmina&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This scenario is Shield CLI's core advantage. Other tunnel tools can only provide "network reachability" here, while users still need to solve "client compatibility" on their own.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 3: Managing Multiple Intranet Services
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Shield CLI: launch Web UI for unified management&lt;/span&gt;
shield start
&lt;span class="c"&gt;# Add multiple applications in the browser, click connect/disconnect&lt;/span&gt;

&lt;span class="c"&gt;# frp: need to edit config files, restart client&lt;/span&gt;
&lt;span class="c"&gt;# ngrok: need to write ngrok.yml, or open multiple terminal windows&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  9. Limitations &amp;amp; Trade-offs
&lt;/h2&gt;

&lt;p&gt;In fairness, Shield CLI has its current-stage shortcomings:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Server is not open source&lt;/strong&gt;: The gateway service is operated by Shield officially (console.yishield.com) and currently cannot be self-hosted. This means data passes through a third-party server. Self-hosted deployment is on the roadmap but hasn't been released yet. frp wins decisively on this point.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Concurrency limits&lt;/strong&gt;: Maximum 3 concurrent connections and 10 saved configurations. Sufficient for individuals and small teams, but inadequate for enterprise scenarios.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No UDP support&lt;/strong&gt;: The underlying Chisel is based on WebSocket (TCP) and doesn't support UDP protocols. frp is more comprehensive in this regard.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Weak access control&lt;/strong&gt;: Currently only Visible mode — "anyone with the link can access." Invisible mode (requiring additional authorization keys) is planned but not yet available. Cloudflare Access's zero-trust approach is an order of magnitude ahead in security.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Community ecosystem&lt;/strong&gt;: As a new project, the community is far smaller than ngrok (GitHub 25k+ stars) and frp (80k+ stars). You may need to read the source code directly when encountering issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;External service dependency&lt;/strong&gt;: While the CLI is open source, core functionality depends on Shield's public gateway. If the service is unavailable, the tool becomes unusable. This contrasts with frp's fully self-contained approach.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  10. Selection Guide
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your Need&lt;/th&gt;
&lt;th&gt;Recommended Solution&lt;/th&gt;
&lt;th&gt;Reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Temporarily expose a local web service to colleagues&lt;/td&gt;
&lt;td&gt;ngrok or Shield CLI&lt;/td&gt;
&lt;td&gt;Both are one-command solutions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remote desktop (RDP/VNC) via browser&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Shield CLI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The only solution that renders desktop protocols in the browser&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fully self-hosted, no third parties&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;frp&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fully open source, self-deployed server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enterprise-grade zero-trust remote access&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Cloudflare Tunnel + Access&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Most comprehensive security policy engine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Usage in mainland China network environment&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Shield CLI or frp&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Domestically reachable installation and service nodes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSH + SFTP file transfer all-in-one&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Shield CLI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Browser-based SSH + SFTP out of the box&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UDP forwarding (gaming, DNS)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;frp&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The only solution supporting UDP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Budget-sensitive, need TCP tunnels&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Shield CLI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ngrok TCP tunnels require payment&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Shield CLI isn't trying to replace ngrok or frp — the problems they solve overlap but aren't identical. &lt;strong&gt;If your core need is "letting others directly operate an intranet desktop or terminal through a browser," Shield CLI is currently the only tool that can do it with a single command.&lt;/strong&gt; It integrates tunnel tools and protocol gateways into a single workflow, eliminating the intermediate step of "installing a client."&lt;/p&gt;

&lt;p&gt;But if you need fully self-controlled infrastructure (frp), enterprise-grade zero-trust security policies (Cloudflare), or simply want to forward an HTTP service (ngrok), those tools each have irreplaceable advantages.&lt;/p&gt;

&lt;p&gt;Technology selection is always about trade-offs. I hope this comparison helps you make a more informed choice for your specific scenario.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Shield CLI open source: &lt;a href="https://github.com/fengyily/shield-cli" rel="noopener noreferrer"&gt;https://github.com/fengyily/shield-cli&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;License: Apache 2.0&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
  </channel>
</rss>
