SSH Accelerated via Cloudflare Preferred Domain: A Postmortem That Kept Turning Into a Mystery Thriller

The SSH “Acceleration Misbehavior Awards”: How We Turned “It Connects” Into “It Finally Connects Reliably”

Let me start with the conclusion so you don’t close the tab halfway through:

  • This setup improves stability, but doesn’t necessarily significantly reduce the latency number.
  • Free Cloudflare + wstunnel can be a lifesaver, but it won’t magically become a leased line.
  • The biggest win is: when you hit similar issues later, you’ll know which layer to check first—instead of relying on vibes.

Chapter 1: 300ms Isn’t Scary—What’s Scary Is “Lagging Like a PowerPoint”

The story starts simple:

  • China to Singapore, ping is 300ms.
  • The business site still looks usable, because there’s a CF reverse proxy and an optimized domain.
  • But the moment you type in SSH, you enter the life stage of “you talk, I’ll pause and reply later.”

So the soul-searching question:

“HTTP can be accelerated—can SSH hitch a ride too?”

Answer: yes, but you have to accept it’s not “one-click magic,” it’s a multi-layer puzzle.

Chapter 2: We Thought It Was the Network—Turns Out the Config Was Fighting Itself

The most mystery-movie part of this was:

  • ssh.cafe.de5.net looks reachable.
  • ssh.aiya.de5.net has a certificate that’s also active.
  • But the client keeps getting connection closed by foreign host, Connection refused, etc.

Later, after narrowing it down, we found:

  • Cloudflare SaaS custom hostnames bring their own Host header when proxying to the origin.
  • If Nginx server_name doesn’t include ssh.aiya.de5.net, it falls through to the wrong site.
  • And then what you see isn’t a “clear error,” but “nothing feels right no matter what.”

One sentence summary:

It’s not down—it’s just that every layer is “almost correct.”

Chapter 3: A 400 in the Browser Is Actually Good News

A lot of people get scared the first time they see this:

Open https://ssh.xxx and you see Invalid protocol request or 400, so you assume it exploded.

But in this architecture, it’s often a good sign:

  • It means the request already reached the wstunnel backend.
  • It’s just that the browser sends HTTP, not the SSH-over-WS protocol stream.

In other words:

  • 400 may mean “the path is reachable but the protocol is wrong”;
  • 404 is more like “it never reached the backend you expected at all.”

Chapter 4: The Client Is the Last Mile (And Also the Easiest Mile to Crash)

Even when the server side is all set, the client can still fail:

  • You think you’re connecting to the accelerated domain, but in reality FinalShell is connecting to 127.0.0.1:10022—and your local tunnel isn’t running.
  • wstunnel version parameter incompatibility: one -v and it immediately throws unexpected argument.
  • In SSH logs you see kex_exchange_identification: Connection closed—the essence is that the tunnel never got established stably.

The correct approach is actually pretty plain:

  1. Run wstunnel client locally first, so local 10022 is listening.
  2. Then let FinalShell/your terminal connect to 127.0.0.1:10022.
  3. If it won’t connect, first check “is the local port listening,” don’t start questioning life.

Chapter 5: So Does It Actually “Speed Things Up”?

This deserves its own section.

Most of the time you’ll get:

  • Latency number: not much change (sometimes basically the same)
  • Perceived stability: noticeably better (no random disconnects, no weird spikes)

Why?

  • Free CF isn’t an Argo dedicated path; it won’t magically erase physical distance.
  • But it can often turn “terrible route jitter” into something more controllable.

So this solution is more like:

Putting a “gimbal stabilizer” on SSH, not swapping in a “lightspeed engine.”

A Pitfall-Avoidance Checklist for Those Who Come After (Condensed)

  1. Confirm the link model first: are you using wstunnel or cloudflared tunnel? Don’t mix concepts.
  2. For SaaS custom hostnames, always check custom_origin_server and whether the origin Host matches.
  3. Nginx server_name must cover the SaaS hostname, or it’ll route to the wrong site.
  4. Opening an SSH domain in the browser and getting 400 isn’t necessarily a bad thing.
  5. On the client side, check local port listening first, then SSH logs.
  6. Set the goal as “stability”—don’t fixate on “latency must go down.”

One Last Line (For You Who Stayed Up Tuning the Network)

The biggest value of this round of tinkering wasn’t “some command finally succeeded,” but that you decomposed a complex chain into verifiable modules:

  • DNS
  • SaaS hostname
  • Origin
  • Tunnel
  • Client

Once you can troubleshoot layer by layer, so-called “mystical network issues” become “ordinary engineering problems.”

Congrats: from being tortured by the network, you’ve evolved into torturing the network.

1 Like