Accessing an external non public resource from your fly.io app

I want to know if fly.io supports the following use case.

Let’s say I want to deploy a golang binary/app in fly.io that needs access to an external resource (let’s say a database) that is not publicly available.

How would you accomplish this?

Can I join the external server (or another host on that network) to the fly.io wireguard net?

Alternatively, I could open a tls/443 port on my end. If I do that, can I run a wireguard peer over websockets and connect both peers. Can I then expose that access to other fly.io apps? I wouldn’t mind creating a new peer on each app.

Anyway, maybe it is crazy but I want to know if anyone has a new for that use case and how they have solved it.

Thank you,
-drd

Yes, you can. It might be a bit of work, though. See also: IPv6 WireGuard Peering · Fly (esp, the part about RDS connectors).

If you desire fancy routing stuff, Kurt recommends tailscale: WireGuard peering without proxy - #2 by kurt | Edit wireguard allowed ips of an app - #2 by kurt

flyctl proxy is another handy little command, if you have the liberty to install flyctl on the remote host: wireguard tunnels from userland - #2 by kurt

Prior art: Can I use fly + WireGuard to expose an internal web interface?

1 Like

Thank you for the reply @ignoramous,

I am trying a little experiment to test this.

As a reminder, what I want to be able to access external resources (at tcp level) and also being able to access my fly apps from my external network (mostly routing http/s traffic).

To that end, I create a fly app (golang server) and a local (runs in my laptop) golang server.

  1. Created a fly app that runs a golang http server. All works well.
  2. I then create a wg tunnel as described here.
  3. Then I start wireguard locally with the configuration generated.
  4. I can access my golang server that runs in fly from my machine. After starting the wg tunnel, fly is resolving dns for .internal. So I run (drio-fly is my app name):
➜ dig +noall +answer _apps.internal txt
_apps.internal.         5       IN      TXT     "drio-fly,fly-builder-shy-smoke-5052"
fly-test/app master [!?]
➜ host drio-fly.internal
drio-fly.internal has IPv6 address fdaa:1:2918:a7b:7a:12b1:7f16:2
# NOTE: sadly,  this is the first time I am going to start using v6 IPs. 

fly-test/app master [!?]
➜ curl http://drio-fly.internal:8080
<!DOCTYPE html>
.... more html stuff

Now I want to be able to test that I can connect to a port in my local machine from the fly app.
For that purpose, I add some http client code in the root handler in the fly webserver. Instead of directly serving the template, I first make a request to the local machine and then I pass the result to the template data.

I believe I can just add the ipv6 address assigned to the network interface in the local machine that fly created for me when I setup the tunnel.

Is there any subcommand I can use from flyctl to test if I can connect/access the local machine from the fly app? Deploying a new version of the app takes time.

Thank you,
-drd

Code: fly-test · GitHub

1 Like

Incredible stuff; living on the literal cutting edge there :wink:

There’s flyctl ping (announcement, docs). So you may try pinging the 6pn (IPv6) address of your local machine’s WireGuard peer from the VM?


Btw, if it works for your usecase, you can consider running flyctl proxy on your local machine instead of creating a WireGuard peer by hand.

Thank you, @ignoramous.

I did not know that it was possible to ssh into an app!
That is great.
Unfortunately I hit an error that I have documented here.

I will continue pushing.

-drd