Skip to content

Commit

Permalink
fix(dgw): better support for ngrok free plan (#718)
Browse files Browse the repository at this point in the history
Our installer is allowing the 0.0.0.0/0 CIDR by default because
premium plans need the IP restrictions to be configured or just
all external traffic. However this doesn’t play well with the free
plan. This patch is using a dirty trick to detect the free plan
and ignores the IP restriction configuration when it is detected.

Issue: DGW-134
  • Loading branch information
CBenoit authored Feb 22, 2024
1 parent 431fe17 commit dc58835
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
24 changes: 23 additions & 1 deletion devolutions-gateway/src/ngrok.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ impl NgrokSession {
Ok(Self { inner: session })
}

pub fn configure_endpoint(&self, name: &str, conf: &NgrokTunnelConf) -> NgrokTunnel {
// FIXME: Make this function non-async again when the ngrok UX issue is fixed.
pub async fn configure_endpoint(&self, name: &str, conf: &NgrokTunnelConf) -> NgrokTunnel {
use ngrok::config::Scheme;

match conf {
Expand Down Expand Up @@ -92,6 +93,8 @@ impl NgrokSession {
builder = builder.compression();
}

let before_cidrs = builder.clone();

builder = http_conf
.allow_cidrs
.iter()
Expand All @@ -102,6 +105,25 @@ impl NgrokSession {
.iter()
.fold(builder, |builder, cidr| builder.deny_cidr(cidr));

// HACK: Find the subcribtion plan. This uses ngrok-rs internal API, so it’s not great.
// Ideally, we could use the `Session` to find out about the subscribtion plan without dirty tricks.
match builder
.clone()
.forwards_to("Devolutions Gateway Subscribtion probe")
.listen()
.await
{
// https://ngrok.com/docs/errors/err_ngrok_9017/
// "Your account is not authorized to use ip restrictions."
Err(ngrok::session::RpcError::Response(e)) if e.error_code.as_deref() == Some("ERR_NGROK_9017") => {
info!("Detected a ngrok free plan subscribtion. IP restriction rules are disabled.");

// Revert the builder to before applying the CIDR rules.
builder = before_cidrs;
}
_ => {}
}

NgrokTunnel {
name: name.to_owned(),
inner: NgrokTunnelInner::Http(builder),
Expand Down
2 changes: 1 addition & 1 deletion devolutions-gateway/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ async fn spawn_tasks(conf_handle: ConfHandle) -> anyhow::Result<Tasks> {
.context("couldn’t create ngrok session")?;

for (name, conf) in &ngrok_conf.tunnels {
let tunnel = session.configure_endpoint(name, conf);
let tunnel = session.configure_endpoint(name, conf).await;
tasks.register(devolutions_gateway::ngrok::NgrokTunnelTask {
tunnel,
state: state.clone(),
Expand Down

0 comments on commit dc58835

Please sign in to comment.