ngrok / ngrok-rust

Embed ngrok secure ingress into your Rust apps with a single line of code.
Apache License 2.0
310 stars 18 forks source link

Not actually connecting to tcp tunnel #147

Open himat opened 1 month ago

himat commented 1 month ago

I think I'm doing something wrong with my code since it's not actually connecting to my account's tcp endpoint

Here's my simple code:

use ngrok::prelude::*;
use tokio::signal;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    listen_ngrok().await?;

    // Wait for a signal to terminate the program
    signal::ctrl_c().await?;
    println!("Shutting down...");

    Ok(())
}

async fn listen_ngrok() -> anyhow::Result<impl Tunnel> {
    let sess = ngrok::Session::builder()
        .authtoken("fds")
        .connect()
        .await?;

    let tun = sess
        .tcp_endpoint()
        .remote_addr("1.tcp.ngrok.io:11111")
        .forwards_to("tcp://127.0.0.1:3128")
        .listen()
        .await?;

    println!("Listening on URL: {:?}", tun.url());

    Ok(tun)
}

When I run this, I see

cargo run
   Compiling ngrok_tunnel v0.1.0 (/Users/hima/monorepo/infra/vpn_tunnel/rust/ngrok_tunnel)
warning: unused implementer of `futures_core::stream::Stream` that must be used
 --> src/main.rs:6:2
  |
6 |     listen_ngrok().await?;
  |     ^^^^^^^^^^^^^^^^^^^^^
  |
  = note: streams do nothing unless polled
  = note: `#[warn(unused_must_use)]` on by default

warning: `ngrok_tunnel` (bin "ngrok_tunnel") generated 1 warning
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.80s
     Running `target/debug/ngrok_tunnel`
Listening on URL: "tcp://5.tcp.ngrok.io:23893"

But it's not actually connected, I'm unable to proxy through my localhost:3128 and when I go to https://dashboard.ngrok.com/cloud-edge/tcp-addresses, this endpoint is not showing up as connected/live.

euank commented 1 month ago

What I think you're running into is a combination of two things.

First, it looks like you want to forward to a local port (3128), but .forwards_to is just setting informational metadata, so that doesn't actually influence things, rather Tunnel::forward_tcp is I believe what you're after

Second, like the warning says, it looks like the tunnel is being dropped before it's being polled for any connections, i.e.

= note: streams do nothing unless polled

I think the minimal fix would be changing main to something like:

-   listen_ngrok().await?;
+   let mut tun = listen_ngrok().await?;
+   let _ = tun.forward_tcp("127.0.0.1:3128").await?;

There's a more complete example of this over in examples here (though the forward_http would probably need to become forward_tcp for this case).

In v0.14 (still in pre-release) there's also a few more helpers around forwarding traffic, so that example has changed a bit. You can use the pre-release version if you'd like to play with that interface instead of course!

Let me know if that helps! I do think the mingrok.rs code in examples is quite close to what you're trying to do, so I think it could be a good starting point, good luck!

russorat commented 2 weeks ago

@himat following up here. Did what @euank mentioned help you?