VPN tunnel for apps
-
For anyone interested in the full VPN Client app's code, I pasted it here: https://github.com/lonkle/openvpn-client-cloudron
Still unfinished. Gonna complete 1.0 and then move it to Cloudron's Git.
-
Quick Ideas for the web interface I wanted to jot down:
• Easy access to common VPN providers
• Attaching VPN app to other app's from within the app itself (using the Cloudron API)
• Saving previous connections for later use
• Not having to restart itself (the app) every connection change (there's no avoiding needing to restart an app that's connecting to it though, that's a limitation of docker unlessdocker network connect --link vpnclientcontainername cloudron container2
would work to mitigate this - it did not in my testing but I know more now, I'll test this again at some point). -
@Lonk I am not sure changes to the reverse proxy code are required at all. Maybe I didn't get a full grasp of your feature request, so let's take a step back.
-
The reverse proxy is only for inbound traffic. It's not used for outbound traffic. It's just a demuxer for incoming http requests to the app containers. My understanding of the feature you suggested was that we want say TTRSS, to use the tunnel for outbound traffic like say when fetching RSS feeds. This means that https://reader.domain.com itself still points to Cloudron but any outbound traffic originating from the container goes via this tunnel.
-
You shouldn't filter by app id etc in docker. Instead, we have to first create a networkId entry in the apps table. Then, app.networkId is then simply the network id to be used in docker.js when creating the container. We don't even have to filter by openvpnclient app etc. The filtering will be done by the dashboard code (i.e in the UI).
I can help out a bit more but I want to first double check if we are in sync about this reverse proxy stuff.
-
-
@Lonk said in VPN tunnel for apps:
@mehdi said in VPN tunnel for apps:
What you should try to achieve is making only the app's outgoing traffic go through OpenVPN, and the connexion between it and Nginx and stuff stay exactly the same as it currently is
That is currently the case as far as I can tell. All incoming traffic bypasses the VPN entirely. Outgoing traffic uses the VPN's connection. But the NGINX needs an incredibly minor change. There's no way around that.
It seems @mehdi nailed it already What is the minor change you require in reverse proxy?
-
@girish Well, @mehdi is correct that that should be how it works. But it has always worked this way.
The problem was never trying to run incoming traffic through the VPN. The problem lies in that if you connect two app's NetworkMode’s together, they have to share the same IP and it removes all network binds to the secondary app (so your healthcheck and nginx routing can't do anything with the info it usually uses). So, the reverse proxy change detects if an app is connected to a VPN Client and if it is, it uses the Docker actual / internal IP and the secondary app’s actual exposed port to route the incoming traffic to.
It can’t use localhost:randomizedport (127.0.0.1:56343) unless we used a second nginx proxy to forward its randomized Docker port
app.httpPort
to its real IP and real exposed port. Docker, in normal circumstances, binds these things for all apps unless their “NetworkMode” is another container - which it is in this case, to make the VPN function.Did I properly explain that / does it make sense?
Note: I'm positive there's a very complicated solution to this that I mapped out and is too ridiculous to implement. But there is a caveat, which is that multiple apps using the same exact
exposedPort
cannot co-exist on the "same network" / connected-to-the-vpn-container. But that's kind of the point of the OpenVPN Client sharing it's network connection, sharing the IP. So, we could restrict one app to connect to one VPN rn to remove "Error: Port Collision" user errors - because you can always install more than One VPN client and connect it to the same VPN. Less work. Don't really see a use case for a a lot of the "same exposed port" apps being used with the same vpn client, but we can let the community decide on that later? -
@girish said in VPN tunnel for apps:
You shouldn't filter by app id etc in docker. Instead, we have to first create a networkId entry in the apps table. Then, app.networkId is then simply the network id to be used in docker.js when creating the container. We don't even have to filter by openvpnclient app etc. The filtering will be done by the dashboard code (i.e in the UI).
100% agreed. I'm only doing that now as a proof of concept because, tbh, I'm not sure where to put this option in the dashboard code (plus dashboard code is harder to work with). So, my hack to filter the other apps to crab the
containerId
of the OpenVPN Client (and using a hardcodedapp.fqdn
conditional to connect to it), I'll use for now until you have time to get together and talk about how to implement this on the front end. -
TODO: Last two things.
• I WILL: Add backend interface to allow a logged in user to submit any .ovpn file via a file chooser and convert it to what Cloudron needs after submitting the new.ovpn
.• @girish MIGHT HAVE TIME TO DO: Modify Dashboard and
appdb.js
to add thevpnclient
'svpnContainerID
andinternalIP
to use inNetworkMode
for any apps choosing to route only their outgoing traffic through the VPN (presumably a drop-down box in the config option of an app which will need to be coded in the dashboard, codes to the ovpn-client's manifest ID - which allows for getting thecontainerID
andinternalIP
of thevpnclient
app).DONE:
Add an HTTP API endpoint to change and convert any .ovpn file a user supplies via POST into the container and disconnect from current to connect to the newly added .ovpnDONE:
Add a front end web interface login page at the base URL of the app which allows for logging in to the app via Cloudron's LDAP -
To anyone who really needs this right now. I just finished with the beta. I've tested it, but there is one manual step needed (you have to copy and paste the "containerName" of your app into a file in the OpenVPN Client File Manager) until @girish has time after 6.0 to add some Dashboard polish to the whole thing in which case the only thing you need to do is add an
.ovpn
file to it's backend, which you simply login with the same credentials you login with Cloudron (since it has LDAP integration) and it'll do the rest. The @girish Dashboard code I think he's adding is a dropdown box to all installed OpenVPN client app's to choose which one you want to connect to (right now, like I mentioned, you have to manually add that to the file inside of the VPN Client's filesystem which isn't very intuitive)". -
Oh, and it may require like 4 or 5 patches to
box
code. Forgot about that. It's fully functional tho, a little unpolished, a lot unpolished. But everything works. @girish and I will work together to integrate it properly at some point after 6.0. My patches run at "start" time, so the fact they're inefficient isn't too big of a deal, but just know that somewhere down the line, @girish and I will add it properly into a stable version of Cloudron. -
@lonk said in VPN tunnel for apps:
Oh, and it may require like 4 or 5 patches to
box
code. Forgot about that. It's fully functional tho, a little unpolished, a lot unpolished. But everything works. @girish and I will work together to integrate it properly at some point after 6.0. My patches run at "start" time, so the fact they're inefficient isn't too big of a deal, but just know that somewhere down the line, @girish and I will add it properly into a stable version of Cloudron.What an accomplishment this was for me back then. I like that my first post in the forums is this crazy hellscape of Cloudron and Docker development jargon. I also wonder if this will ever help anyone down the road. Either way, I'm glad this whole thing is archived, it's p nostalgic for me. ️
-
-
I use gluetun at home with an OpenVPN-based VPN service, and it works like a charm.
Not sure how we would implement it in cloudron, though.At my home server I use a docker-compose file with all the services, and on the ones I want to use the VPN, I use
network_mode: service:gluetun
.Gluetun also needs
NET_ADMIN
capability enabled.