Cloudron makes it easy to run web apps like WordPress, Nextcloud, GitLab on your server. Find out more or install now.


    Cloudron Forum

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular

    VPN tunnel for apps

    Feature Requests
    openvpn networking
    7
    135
    2685
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • girish
      girish Staff last edited by

      @Lonk Thanks for the encouragement 🙂 and let us know if you need help finishing up the client part.

      Do you know how docker behaves when it comes to routing? There is a docker network attach that lets us attach the container to multiple networks. This is required on Cloudron because the addons like databases are in a network named cloudron. With your app, we will attach the app to the vpn client and cloudron network. I wonder how we can "route" all internet traffic via the vpn client. I can't find any obvious docs for this.

      1 Reply Last reply Reply Quote 1
      • mehdi
        mehdi App Dev last edited by

        I think automatically detecting and proposing "network providers" apps in a dropdown would not be very easy... Plus, I think a lot of other apps would benefit from "providing" services to other apps, like a minio instance could provide object storage for other apps.

        But this is a big undertaking in my opinion.

        In the meantime, simply providing an UI to add custom docker options manually would do the job I think. It would not be as easy to use, but with a little bit of doc it should be doable even for someone who doesn't know docker inside and out. Plus, it would obviously allow a lot of other customizations.

        1 Reply Last reply Reply Quote 2
        • girish
          girish Staff last edited by

          I think maybe adding fields to manifest etc to identify network client might be an overkill right now. What I was thinking is just to have an API to set an existing app id as the container's network. This is easy for the backend to do, we have to simply issue docker network attach. For the frontend dropdown, it can simply filter out network providers based on the manifest appstore id for now (hardcoded to openvpn client). Should be fine.

          But I think the bigger thing to be figured out is how the routing works.

          1 Reply Last reply Reply Quote 0
          • Lonkle
            Lonkle last edited by Lonkle

            @girish Would docker connect work better in this regard? And also, I agree with the hardcoded dropdown to "openvpn-client" (manifest appstore id).

            This is how I do it locally with just Docker:

            docker run -it --cap-add=NET_ADMIN --device /dev/net/tun --dns 8.8.8.8 --name openvpn-client -e "CONNECTION_TIMEOUT=-1" -p 3000:3000 lonk/openvpn-client:latest

            That starts the OpenVPN Client Docker and connects it to vpn.conf (a hardcoded VPN server). I set the DNS because the VPN can't seem to get the DNS otherwise for some reason, and I set the port because the other container needs that port to be open.

            So then I connect my next Docker container to the VPN Client container at runtime:

            docker run --name chrome -"CONNECTION_TIMEOUT=-1" --net=container:openvpn-client viridiancloud/chrome:latest

            This works perfectly locally, the chrome container runs everything through the VPN if I pass the --net=container:openvpn-client on runtime. I'm trying to get the puppeteer container to use the network of the openvpn-client while it's still running now. Experimenting with docker network connect now on my localhost.

            I may need to create a network somehow and assign the OpenVPN Client Docker to that. Looking into it now so we can further understand how to get this working in the cloudron network context (or in addition to it since containers can connect to multiple networks at once).

            girish 1 Reply Last reply Reply Quote 0
            • girish
              girish Staff @Lonkle last edited by girish

              @Lonk said in Better documentation for the API:

              Would docker connect work better in this regard

              Is this a new command? Atleast, I don't have this in my docker 19.03.12.

              $ docker connect
              docker: 'connect' is not a docker command.
              See 'docker --help'
              

              edit: don't mind me, I guess they are just typos. docker network connect and docker network attach, I guess. I wasn't aware of this connect subcommand.

              edit2: there is no, docker network attach 🙂 I meant docker network connect all the time.

              Lonkle 2 Replies Last reply Reply Quote 0
              • Lonkle
                Lonkle @girish last edited by

                @girish said in VPN tunnel for apps:

                there is no, docker network attach I meant docker network connect all the time.

                Okay, that makes a lot of sense, when you mentioned the "network" attach command, I figured I had some reading up to do. 😂

                I edited my post to fix my typo and remove mentions of "docker attach".

                Lonkle 1 Reply Last reply Reply Quote 0
                • Lonkle
                  Lonkle @girish last edited by Lonkle

                  @girish I have finished converting the app into a Cloudron app and have pushed it to the Docker Hub, there appears to be one issue with these two lines in the start.sh file:

                  mkdir -p /dev/net
                  [[ -c /dev/net/tun ]] || mknod -m 0666 /dev/net/tun c 10 200

                  There seems to be an issue with this part of the starting script. Likely related to this docker run argument that I run locally --device /dev/net/tun. This is the exact error I get when attempting to run it on Cloudron (despite it successfully running locally with strictly Docker).

                  ERROR: Cannot ioctl TUNSETIFF tun: Operation not permitted (errno=1)

                  What do you think on the Cloudron side of things there?

                  1 Reply Last reply Reply Quote 0
                  • Lonkle
                    Lonkle @Lonkle last edited by

                    @Lonk Note: I submitted the DockerHub link for you here (https://www.cloudron.io/app-developer.html) to pull and test yourself locally via docker run -it --cap-add=NET_ADMIN --device /dev/net/tun --dns 8.8.8.8 image/name (which will succeed, just try curl icanhazip.com in the Docker container and it will see a different IP address). Then check the logs on cloudron when trying to install to it and you'll see the issues with /net/tun that don't exist locally.

                    1 Reply Last reply Reply Quote 0
                    • girish
                      girish Staff last edited by

                      @Lonk Have you pushed the package source code somewhere?

                      1 Reply Last reply Reply Quote 0
                      • girish
                        girish Staff last edited by

                        For the tun device stuff, @mehdi solved it by creating the device in Dockerfile - https://git.cloudron.io/cloudron/openvpn-app/-/blob/master/Dockerfile#L30 (RUN mknod /app/code/net-tun c 10 200) and then using dev-node /app/code/net-tun option in openvpn.conf

                        Lonkle 1 Reply Last reply Reply Quote 0
                        • mehdi
                          mehdi App Dev last edited by

                          It's quite a long time ago now that I wrote the openvpn-server app, but I remember that this ton device stuff was hell 😛 (Plus, Cloudron did not have support for capabilities like NET_ADMIN back then, so I had to implement that in the server itself^^)

                          @Lonk in your command line, you forward the host's /dev/net/tun device to the container, which cloudron does not do, so the problem probably comes from there.

                          If @girish's suggestion of using the same trick as the openvpn-server app does not work, I'd be happy to take a look.

                          1 Reply Last reply Reply Quote 0
                          • Lonkle
                            Lonkle @girish last edited by Lonkle

                            I worked on this for a few more hours tonight and after editing the starting script and DOCKERFILE (and a dumb mess up with CloudronManifest.json), I now have it 100% working within Cloudron.

                            Thank you so much for your help @girish / @mehdi!

                            There's a bunch of polish now that needs to be made. Proper healthcheck since this doesn't have a web admin exposed yet. I'll be making a custom web admin to change out VPN files (.ovpn) and credentials to make this a proper web app for Cloudron. For now, I'm just going to fake the healthcheck in testing just to see if we can connect containers using @girish Cloudron's code edit idea to make another container use my OpenVPN Client's Container's Network (akin to docker run's --net=container:vpn-client command).

                            PS. @girish, I haven't published the code on Github yet because I've hardcoded my home's VPN credentials in there since this is just a proof of concept. I gave you guy's the DockerHub link through this form: https://www.cloudron.io/app-developer.html - so that only you guys would know the link to pull it to Cloudron. Once I make the VPN configurable, I'll be releasing the source. I'll fix the health check in the morning with v0.3. Until then, feel free to pull the image to Cloudron to install for your own testing purposes (the idea you had to make it connect to other Cloudron apps). If you don't have time to, or are unable, I can take a stab at editing the Cloudron code directly. Let me know! ☺️

                            1 Reply Last reply Reply Quote 1
                            • Lonkle
                              Lonkle last edited by Lonkle

                              Alright, v0.3 release notes:

                              • Uses cloudron:2.0 base image now.
                              • Added apache to start the process of configuring a web interface (it'll need to do a few things like add dev-node /app/code/net-tun to the openvpn-server.ovpn files and convert them into vpn.conf files (which is stored in app/data so it's persistent and can change at anytime through an API endpoint I'm going to write...for now, you can change the file yourself and add it in the Cloudron File Manager and then restart the app).
                              • Fixed the healthcheck so that Cloudron now runs it as a full fledged app

                              This is at the point where I'm ready to upload it to Github tonight and I'll post the link. I just need to revoke my personal OVPN Server certificate first before I do that and I have some more testing when it comes to the web interface and modifying files.

                              @girish Do you have any questions from me in order to make your side of things (Cloudron's base code) connect to this container's network to other apps on Cloudron? Were you able to find and pull my testing image from the DockerHub through the form I submitted - which I did get a response, as I'm now in the contributor program 🎉 and I'm happy to be because developing with Cloudron is just getting more and more fun. I have some ideas for Wordpress which is where my real expertise is. I'll finish this project and then move onto that after you guys release 6.0 (since I know it's coming with Wordpress changes).

                              1 Reply Last reply Reply Quote 3
                              • girish
                                girish Staff last edited by girish

                                @Lonk Thanks! It might be easier for me to test with the package source. On Cloudron, you will need the manifest file to install and not just the docker image anyway.

                                I am happy to look into the Cloudron side of things whenever the package is semi-ready. Thanks for all the work!

                                Lonkle 2 Replies Last reply Reply Quote 0
                                • Lonkle
                                  Lonkle @girish last edited by Lonkle

                                  @girish My DockerHub link you can pull to Cloudron and install comes with the Cloudron manifest So, rn, it’s working perfectly as an app in Cloudron now, fully operational (just doesn’t have a web interface to change the OVPN file yet but contains everything you need to test it, directly connects to my homes VPN until I revoke the cert which I didn’t want to do until you were done testing). I’ll post the source on GitLab today minus the hardcoded .ovpn file. But can I send you that specific file personally so you can use it for testing. You just place it in the /app/data folder and restart the OpenVPN Client app and your IP for that container will magically change. 😂 So you can then test connecting another app to it network-wise (a la a cloudron eqivalent to docker run's --net=container:vpn-client runtime argument) and then curl icanhazip.com the “connected-to-the-vpn-client” app to see if it gets the same IP address as the OpenVPN Client Cloudron app.

                                  Does all of that make sense?

                                  1 Reply Last reply Reply Quote 0
                                  • Lonkle
                                    Lonkle @girish last edited by Lonkle

                                    @girish I removed the pre-configured .ovpn file that is in the DockerHub version of 0.3 and added the full source code to Github. I tried adding it to Cloudron's Gitlab but it didn't let me create a repository for some reason so I just used Github.

                                    https://github.com/lonkle/openvpn-client-cloudron

                                    If you need my preconfigured .ovpn file for testing instead of creating your own (you can add your converted .ovpn file and rename it to vpn.conf to the root directory before you install or after the install with the Cloudron File Manager, but if you do that you have to restart the app for it to take effect), then let me know so I can send it to you privately. I'll revoke my pre-configured one when you're done testing if you want to go that route (pun intended 😂).

                                    1 Reply Last reply Reply Quote 0
                                    • Lonkle
                                      Lonkle last edited by Lonkle

                                      Goals for v0.5.0:

                                      • 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 .ovpn

                                      Goals for v1.0.0 (I'd consider it ready to upload to the official Cloudron Appstore at this point):

                                      • Add a full web interface at the base URL of the app which uses the API endpoint in v0.5 to allow a user to submit any .ovpn file and convert it to what Cloudron needs to straight from a web interface (so they don't have to use the API or manually add it in the terminal / file manager, which would be confusing to new users using Cloudron).

                                      @girish Neither of these final features will be needed for you to do your testing whenever you'd like to connect one or multiple containers networks to the the "OpenVPN Client v0.3" app's network. So let me know a good way to send you my preconfigured vpn.conf file for you to use to test the feature. In the end, the API backend will automatically convert any .ovpn files supplied by a user via the API or web interface into a format Cloudron needs; mine is just pre-configured for ya so you don't have to make your own just to test networking between the containers.

                                      1 Reply Last reply Reply Quote 1
                                      • Lonkle
                                        Lonkle last edited by Lonkle

                                        @p44 I built the OpenVPN Client you can use to change your IP for your app. @girish offered to add a custom feature to Cloudron specifically to allow Cloudron apps to network connect to my OpenVPN Client app. So, not much longer now! I might try to dive into the network code myself but I'll admit, Cloudron's base code intimidates me. 😅

                                        mehdi P 2 Replies Last reply Reply Quote 0
                                        • mehdi
                                          mehdi App Dev @Lonkle last edited by

                                          @Lonk Give it a try, it's not that hard ! I had to do it for the OpenVPN server, it's only fair that you do it for the OpenVPN client 😛

                                          Lonkle 1 Reply Last reply Reply Quote 1
                                          • Lonkle
                                            Lonkle @mehdi last edited by Lonkle

                                            @mehdi Alright alright, you've convinced me - Is the flow similar to app creation to build it locally? Won't I need another license to start working on Cloudron locally though? So, the cloud can stay up, and I can develop this multiple app network VPN connection code locally? Normally, I could just use the free license for local dev, but I literally need three apps to test this because coincidentally this modification needs a total of 3 simultaneously running apps to test, the Open VPN Client App, another app to connect to it's network (so one to one connection is tested and confirmed), and then another app to simultaneously (3 apps needed to be installed at once to test) connect to the same Open VPN Client App's network.

                                            I also just read on Gitlap that some of Cloudron is closed source, hmm, I should focus my feature requests on the closed source aspects I literally can't change myself and then merge request it.

                                            1 Reply Last reply Reply Quote 0
                                            • Lonkle
                                              Lonkle @girish last edited by

                                              @girish said in VPN tunnel for apps:

                                              Step 2 is to then have some configuration to let apps use this container as the networking layer. If you ignore the UI/UX, this is really just a one-line change: https://git.cloudron.io/cloudron/box/-/blob/master/src/docker.js#L311 will be changed to the VPN client app's container. If we had a way to identify vpn clients, we can just have a dropdown of vpn clients as the available 'networks' in the app's configuration UI. And that should be it.

                                              https://github.com/lonkle/openvpn-client-cloudron

                                              I am finished with the MVP, it'll be ready for the App Store as soon as I include instructions on install to show the user installing it how to get their .ovpn in the /app/data folder for the OpenVPN Client to pick it up and some other small polishes (like using a wildcard to pick up whatever .ovpn file they put into /app/data and adding the necessary one-liner automatically to the file for it to be compatible with Cloudron's network. But, as of now, every time you change OVPN servers, you have to restart the app. I'm going to use the Cloudron API to do this manually but I haven't found a way to not restart the app yet and just disconnect + connect to a different server on-demand, just at initial runtime.

                                              Oh, and when you need an .ovpn for testing container network connections, let me know! But I'm gonna take a stab (no promises, nervous at how different the Cloudron base code is gonna be 😬) at getting this working myself on the Cloudron side. Thanks for pointing me in the right direction!

                                              1 Reply Last reply Reply Quote 0
                                              • Lonkle
                                                Lonkle last edited by Lonkle

                                                Okay, I'm close to finalizing the Cloudron side of things. But I can't seem to find a function like

                                                getContainerIdByAppId('com.joelstickney.openvpn-client')

                                                @girish Do you know any functions off-hand or maybe some files that I should be lookin’ into? I need the Open VPN client's (sub)Container ID so I can apply it to the other (sub)Containers network(s).

                                                1 Reply Last reply Reply Quote 0
                                                • Lonkle
                                                  Lonkle last edited by

                                                  I wish I had a better deployment system for cloudron:box changes, this is much harder than regular app development. But that's probably a testament to how well Cloudron's app "subcontainer" packaging system is built.

                                                  1 Reply Last reply Reply Quote 0
                                                  • Lonkle
                                                    Lonkle last edited by

                                                    I did find a getAll(callback) and even a more specific getByFqdn(fqdn, callback) lines I may be able to use to get the container ID of my Open VPN Client.

                                                    1 Reply Last reply Reply Quote 0
                                                    • Lonkle
                                                      Lonkle last edited by

                                                      I'm now able to connect any container to any network I want on app startup based on the app's FQDN or ID. But even if I create a separate network than cloudron and stick the OpenVPN Client in there with another app. The other app doesn't inherit the OpenVPN Client's IP like it does when you connect the connectors directly on the bridge network using the docker run --net command.

                                                      There may be a firewall issue though. Cloudron does have a very specific subnet and maybe I can't escape it without running into a firewall.

                                                      @girish @nebulon - any ideas for me on this one?

                                                      1 Reply Last reply Reply Quote 0
                                                      • girish
                                                        girish Staff last edited by

                                                        Oh wow, you are moving way faster than we can take a look at this. Great progress. Please give us a day or two to look into this! mon/tue is always a bit slower given all the app updates, support requests etc that pile up over the weekend 🙂

                                                        Lonkle 1 Reply Last reply Reply Quote 0
                                                        • Lonkle
                                                          Lonkle @girish last edited by

                                                          @girish No problem at all. I can work on porting some other apps in the meantime. Really love the platform you guys created.

                                                          And I might be able to figure the answer to my own question. I made an Ubuntu Graphical 18.04 Virtual Machine and installed Cloudron on that so I can develop for the “above subcontainer level” (AKA: box) app code. I am tho running into the two app restriction on localhost - I wish that limitation didn’t apply to custom apps developers are making.

                                                          Anyway, thank you again for being as responsive as you have been and don’t mind me updating as I go. Respond whenever you think you can. ☺️ You guys have done some really amazing work; both of you are inspirations tbh.

                                                          1 Reply Last reply Reply Quote 0
                                                          • girish
                                                            girish Staff last edited by

                                                            @Lonk If you are working on app, please do leave a note in the corresponding app's wishlist topic. Just to make sure all our work does not overlap. Thanks.

                                                            Lonkle 1 Reply Last reply Reply Quote 0
                                                            • girish
                                                              girish Staff last edited by

                                                              BTW, does the vpn client have some sort of web ui? Would be great to have something where a user can just login and provide connection information. We can look into the openvpn server app for inspiration.

                                                              Lonkle 1 Reply Last reply Reply Quote 1
                                                              • Lonkle
                                                                Lonkle @girish last edited by Lonkle

                                                                @girish
                                                                Goals for v0.4.0:
                                                                • Modify docker.js to use the container:vpnContainerID NetworkMode for all apps choosing to run their 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, hardcoded to the ovpn-client's manifest ID). Note: Need to remove hostname and any port bindings so that the container takes on the attributes of the VPN otherwise the NetworkMode will conflict with the VPN Client's Network.

                                                                Goals for v0.5.0:
                                                                • 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 .ovpn

                                                                Goals for v1.0.0 (I'd consider it ready to upload to the official Cloudron Appstore at this point):
                                                                • Add a full web interface at the base URL of the app which uses the API endpoint in v0.5 to allow a user to submit any .ovpn file and convert it to what Cloudron needs to straight from a web interface (so they don't have to use the API or manually add it in the terminal / file manager, which would be confusing to new users using Cloudron).

                                                                1 Reply Last reply Reply Quote 0
                                                                • Lonkle
                                                                  Lonkle @girish last edited by

                                                                  @girish And I will post on each app's wishlist forum post when I start work on converting.

                                                                  I'm just really stuck on this NetworkMode code. No matter what I do, the NetworkMode stays cloudron even after restarting the container and hardcoding it to use the NetworkMode container:vpncontainerid. Effectively making the app useless. The NetworkMode needs to change, but it's like once the NetworkMode is attached to an app, it stays on there no matter what. Still experimenting as that's the last piece of this puzzles aside from finding a function that can take a cloudron-manifest-id and translate it to a Docker Container ID (so I don't have to docker network inspect and then hardcode it's ID).

                                                                  mehdi 1 Reply Last reply Reply Quote 0
                                                                  • mehdi
                                                                    mehdi App Dev @Lonkle last edited by

                                                                    @Lonk Are you sure you are re-building the app container, not just re-starting it ?

                                                                    Lonkle 1 Reply Last reply Reply Quote 0
                                                                    • Lonkle
                                                                      Lonkle @mehdi last edited by Lonkle

                                                                      @mehdi My OpenVPN Client doesn't require any more edits to work on Cloudron. Or are you referring to the "other container" that I'm trying to attach to my OpenVPN Client (to then change it's public IP which I just check with curl icanhazip.com every new experiment)? So all apps / cloudron containers I just restart from the Cloudron dashboard since they are the one's who's NetworkMode needs to be container:vpn-docker-constainer-id-or-name-but-really-just-id (it's hard to parse containters and networks because docker.js has to sent the app names to their container ids to prevent container naming conflicts) - which is a box problem that needs to be solved (particularly docker.js).

                                                                      I see a lot of mentions of appContainer references and subcontainer references in REing the docker.js code. But they're all just regular containers (nothing is special about them except a flag is set if it's.a subcontainer) so that must be a Cloudron nomenclature.

                                                                      I think (really just hope) I found my issue:
                                                                      function containersCreate(req, res, next) { safe.set(req.body, 'HostConfig.NetworkMode', 'cloudron'); // overwrite the network the container lives in

                                                                      Now why are you doing that to me @girish? 😂

                                                                      1 Reply Last reply Reply Quote 1
                                                                      • Lonkle
                                                                        Lonkle last edited by

                                                                        THAT WAS IT! Well, there's more to box code changes than just proving the vpn client connection works. But @girish was overriding the network name in dockerproxy.js which took an entire day to figure out! 😂 but really 😭

                                                                        Alright, @mehdi, I'm glad you pushed me enter into box code realms. I'm still intimidated by it. But I've got (sub)container creation down pretty well now. 🎉

                                                                        1 Reply Last reply Reply Quote 1
                                                                        • Lonkle
                                                                          Lonkle last edited by

                                                                          This would be faster using Cloudron on localhost in my VM as I installed it on yesterday to do box code. But, the two app limit thing was too hard to deal with.

                                                                          1 Reply Last reply Reply Quote 0
                                                                          • Lonkle
                                                                            Lonkle last edited by

                                                                            One of the worst parts of box code is that all these containers (aside from contained cloudron services and cloudron itself) have hshes for names. So, when trying to connect one to another and then inspecting the attributes of all of them is so confusing.

                                                                            1 Reply Last reply Reply Quote 0
                                                                            • Lonkle
                                                                              Lonkle last edited by

                                                                              To get this app store ready, it might even need modifications to the nginx reverse proxy. @mehdi Maybe you can help? Is there a way, in cloudron to open more than one port? The manifest seems to be a way to publish a random port to forward to the specified-in-the-manifest port

                                                                              Example:

                                                                              Using docker container ls --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}" -a - I can look at all the "published" ports. They all seems to be going through a nginx reverse proxy to reach port 80 / 443. And their original port that forwards to that is random (?).

                                                                              NAMES ----------------------------------- PORTS
                                                                              0b993ea5-85fc-4465-af5f-a1cd5ea5aeb7 127.0.0.1:43641->8080/tcp
                                                                              57c94244-112d-4b98-abc4-0f15d6b07ca7 127.0.0.1:40875->8000/tcp
                                                                              10a9ae64-689e-4765-a990-89a3d5e400d2 127.0.0.1:44749->80/tcp

                                                                              1 Reply Last reply Reply Quote 0
                                                                              • Lonkle
                                                                                Lonkle last edited by

                                                                                Maybe if I hardcode the bind address to 0.0.0.0. Cloudron hardcodes it to localhost (likely for security purposes).

                                                                                1 Reply Last reply Reply Quote 0
                                                                                • Lonkle
                                                                                  Lonkle last edited by

                                                                                  Sorry about the spam, I just started learning Docker two weeks ago now when I started building this app, so it's been all very foreign to me. Had to learn so many weird networking things.

                                                                                  1 Reply Last reply Reply Quote 0
                                                                                  • Lonkle
                                                                                    Lonkle last edited by

                                                                                    I'm having a reverse proxy battle. Everything works now, but the "connected-to-the-vpn-client" app can't access the outside world. Cloudron doesn't publish ports in the standard way, there's some proxy between it all, and I have to RE that to get the apps connected to the openvpn-client to use the proxy somehow. It should just work by default looking at the code, but - there's always something.

                                                                                    1 Reply Last reply Reply Quote 0
                                                                                    • Lonkle
                                                                                      Lonkle last edited by Lonkle

                                                                                      Okay, so there's a problem here:

                                                                                      appPortBindings.hostPort needs to be set for all of Cloudron's containers or Cloudron turns them off. The only reason I know my OpenVPN client works is because I curl icanhazip.com before box stops the container for not passing all of it's "checks."

                                                                                      But this is a special case. To connect to the VPN Client - the app container can't have a hostPort as it inherits that from the VPN Client as part of the connection. But Cloudron requires the App published to have a port (I hardcode it not to), so even though the app works, Cloudron will stop it from running eventually once it fails enough checks until I figure out how to deal with this reverse proxy thing works.

                                                                                      1 Reply Last reply Reply Quote 0
                                                                                      • Lonkle
                                                                                        Lonkle last edited by

                                                                                        I just have to figure out how to let appdb.js know that there's an actual http port set, it's just not in the **connected-to-vpn-client's`` app / container, it's defined in the OpenVPN Client's app / container.

                                                                                        Barring figuring that out though, I have to have the openvpn-client app mirror the ports that are exposed for every app connnected to it (right now, I'm just letting one container connect since Cloudron doesn't support more than one exposed port). Ahhh, so basically the OpenVPN client's http port has to be variable depending on the connecting app (or apps if people want to connect more than one other app to it at a time - I only personally need one app connected to it). So that's manifest.js code to also modify to get this to work.

                                                                                        1 Reply Last reply Reply Quote 0
                                                                                        • Lonkle
                                                                                          Lonkle last edited by Lonkle

                                                                                          I'm climbing a mountain too tall for me rn. 😬

                                                                                          1 Reply Last reply Reply Quote 1
                                                                                          • marcusquinn
                                                                                            marcusquinn last edited by

                                                                                            The first step in making any tunnel is digging a hole 😂

                                                                                            We're not here for a long time - but we are here for a good time :)
                                                                                            Jersey/UK
                                                                                            Work & Ecommerce Advice: https://brandlight.org
                                                                                            Personal & Software Tips: https://marcusquinn.com

                                                                                            1 Reply Last reply Reply Quote 0
                                                                                            • Lonkle
                                                                                              Lonkle last edited by

                                                                                              Nice metaphor for a VPN tunnel app. 😂 I’m so close to get this working. I found the SQL that inserts the httpPort into the DB so I’m going to try to have the container “attaching to the openvpn client” inherit the port and port type from the VPN Client while still having it be discoverable by the database. Let’s hope this works. 😬😅🤞

                                                                                              1 Reply Last reply Reply Quote 1
                                                                                              • Lonkle
                                                                                                Lonkle last edited by

                                                                                                Alright, I got the container both running and entered into the database (I'm pretty sure). So Cloudron can "see" the app. I copied the exposed and host ports to the container returned at the end of createContainer while nulling them during the containers initialization.

                                                                                                That seems to be enough for app discovery, now to see if I can get the reverse proxy working which will be the last piece of the puzzle I hope.

                                                                                                1 Reply Last reply Reply Quote 1
                                                                                                • marcusquinn
                                                                                                  marcusquinn last edited by

                                                                                                  Dig, Forest, Dig! 🕳 😂

                                                                                                  We're not here for a long time - but we are here for a good time :)
                                                                                                  Jersey/UK
                                                                                                  Work & Ecommerce Advice: https://brandlight.org
                                                                                                  Personal & Software Tips: https://marcusquinn.com

                                                                                                  Lonkle 1 Reply Last reply Reply Quote 1
                                                                                                  • Lonkle
                                                                                                    Lonkle @marcusquinn last edited by

                                                                                                    @marcusquinn I’m not positive but I think the Nguni reverse proxy is being fed a null or 0 hostPort. The exposedPort is part of Cloudron’s environment variables. Maybe I’ll add the hostPort to that and read it back during reverse proxy configuration. 🤔

                                                                                                    1 Reply Last reply Reply Quote 0
                                                                                                    • Lonkle
                                                                                                      Lonkle last edited by

                                                                                                      I hope nobody finds me logging my development on this app to be annoying. I needed a place to keep all of these new concepts in my head. I’ve never worked with Docker or Cloudron before this month and I’m trying to jot down my experiences for me to read later until I complete this.

                                                                                                      If I hardcode the health checks to all pass. My app connected to the VPN stays connected and it’s terminal working but never gets past the “Starting” phase until it times out in like ten minutes (the reverse proxy doesn’t work so neither does Let’s Encrypt...which then times out the app). This is because it’s reverse proxy isn’t set up correctly. I believe that the NGINX reverse proxy either gets the wrong hostPort or the wrong exposedPort or both.

                                                                                                      I’m actually amazed that I got this far. Because both the hostPort does make it into the database now for it to be discoverable by Cloudron. But why the reverse proxy WriteNginxReverseConfig receives different info than `apps.js’ “add-to-db” function (since that happens first) is really confusing. I’ll keep working on it though. I can’t hardcode (wellll...I technically can for the same container but don’t want to).

                                                                                                      Another problem is that my NetworkMode to container changes only (for now) take effect upon installation. Have to figure out why that is - but I also have some guesses.

                                                                                                      Nobody told me box code was this hard. 😂

                                                                                                      1 Reply Last reply Reply Quote 1
                                                                                                      • Lonkle
                                                                                                        Lonkle last edited by

                                                                                                        And I’m still using the app’s FQDN variable to hardcode its attachment to the VPN rather than its manifest ID since I can’t find the function to read an app’s manifest to get its ID. 😅 So much more work to be done (I need the VPN client’s containerCreate option exposedPort(s) to be variable depending on its ID and the app connecting to it) - which is another reason I need to learn to use manifest data. But that’s a simple function I’m sure I’m missing somewhere. @girish - do you know it off the top of your head?

                                                                                                        1 Reply Last reply Reply Quote 0
                                                                                                        • mehdi
                                                                                                          mehdi App Dev last edited by

                                                                                                          I suddently have a doubt about what your goal is ...

                                                                                                          Are you trying to make the app itself, when it tries to connect to an external service, use the VPN, but still be exposed through normal internet?

                                                                                                          Or are you trying to restrict the users from accessing the app itself if they are not going through the VPN?

                                                                                                          1 Reply Last reply Reply Quote 0
                                                                                                          • Lonkle
                                                                                                            Lonkle last edited by Lonkle

                                                                                                            I’m trying to accomplish your first idea.

                                                                                                            I made a Cloudron app called “OpenVPN Client” and it works perfectly. It can connect to any OpenVPN Server. I put a basic Apache configuration in front of it just to pass the Cloudron’s Health Check.

                                                                                                            Now, my use case is to have a singular other app (any app, but I’m using the basic LAMP from the Cloudron store for testing) route all of that app’s traffic through my OpenVPN Client app. I understand other users may want to connect more than one other app and it’s technically possible to do so via setting their NetworkMode to container:open-vpn-id - but that introduces an extra complexity of exposing more than one port which Cloudron cannot do rn (but is technically possible if girish wanted to make those edits). I don’t mind though since my use case is a 1:1 OpenVPN Client + Other Cloudron app connection.

                                                                                                            That’s the entire thing in a nutshell. I’ve had to dig into a lot of box code to understand how to make it happen but my OpenVPN Client app is completely working and even passes all the Cloudron health checks but the singular app connecting to it and routing all of its web traffic through it does not pass the Cloudron Healthcheck because a container connecting to the network of another container is forced to inherit all the network properties of that container. That means, the reverse proxy sees no hostPort (Cloudron is looking for it in the wrong place) when trying to configure the app and thus literally stays in the **Starting up...” statuses (with it’s terminal working and traffic is verified routing through the OpenVPN Client).

                                                                                                            robi 1 Reply Last reply Reply Quote 0
                                                                                                            • robi
                                                                                                              robi @Lonkle last edited by

                                                                                                              @Lonk sounds like you need an internal network interface for internal liveness checks and external interface for the outgoing VPN traffic and it's checks.

                                                                                                              otherwise you're forced to check liveness on the wrong app just because it's routing through it.

                                                                                                              Life of Gratitude.
                                                                                                              Life of Advanced Technology

                                                                                                              Lonkle 1 Reply Last reply Reply Quote 0
                                                                                                              • Lonkle
                                                                                                                Lonkle @robi last edited by Lonkle

                                                                                                                @robi Well, the thing is. The second app should pass all the health checks just fine. It’s a web app after all that is exposed to the web (right now testing with the LAMP stack’s homepage). The only reason it doesn’t pass the check (which makes Cloudron stop the container) is because Cloudron is setting up the reverse nginx config incorrectly due to it believing the Cloudron app just installed has no hostPort even though it really does.

                                                                                                                The nginx reverse config needs to account for this to make the second app connected to the VPN Client app to even work. Because right now all I can do is use its terminal to prove its working. But the Cloudron network is setup in such a way that it’s needed to reverse proxy it’s hostPort to its exposedPort.

                                                                                                                My newest idea is to write the Docker randomized hostPort as part of the Cloudron environment variables it holds and then use that in the Nginx Reverse Proxy config if the starting app doesn’t appear to have one.

                                                                                                                Working on box code is harder than app code (especially because I can’t access its database outside of the command line and, well...I don’t really know SQL syntax). But shoutout to @nebulon for making it easier for me!

                                                                                                                1 Reply Last reply Reply Quote 1
                                                                                                                • Lonkle
                                                                                                                  Lonkle last edited by

                                                                                                                  This also leads to the discussion of exposedPorts in the OpenVPN Client app's side of things. Right now, it has to mirror each of it's connected containers (their can be multiple) exposed ports, but Cloudron (for good reason) has restricted app's exposed ports to one.

                                                                                                                  Dynamically assigning just the OpenVPN's exposed port(s) on demand (to logically sync up with the app that's connecting to it) is needed here and does 100% require a restart of the OpenVPN Client app unless we decide to go the route of opening x amount of the common ports and restricting multiple Cloudron app's from connecting to the OpenVPN Client to one exposed port per app (which ironically could be worked around with a dynamically assigned port forwarding to the real second containers port which then finally reverse proxies onto the hostPort + port 80 / 443 - but that seems like two much work just to connect more than one app per exposedPort at a time).

                                                                                                                  1 Reply Last reply Reply Quote 0
                                                                                                                  • mehdi
                                                                                                                    mehdi App Dev last edited by

                                                                                                                    (Disclaimer: I am no expert on docker networking magic)

                                                                                                                    I think instead of trying to find a way to expose the ports from the OpenVPN container, you should instead try and find a way to make it work directly from the app container itself.

                                                                                                                    Even if you do make it work for the exposedPort (which, I think, refers to the main web port exposed by the app, the one which is behind the reverse proxy, to expose its web interface and such, that's why there's only one: there's only one web interface), you're gonna have trouble with the extra ports (the ones defined in the manifest here https://docs.cloudron.io/custom-apps/manifest/#tcpports ) for apps that use these.

                                                                                                                    Lonkle mehdi 2 Replies Last reply Reply Quote 0
                                                                                                                    • Lonkle
                                                                                                                      Lonkle @mehdi last edited by Lonkle

                                                                                                                      @mehdi Well, that would only need to be a box discussion if we wanted more than one other Cloudron app to connect to it at a time. It'd be an interesting discussion on how to make it work with no caveats. But I personally don't see a need to have more than one container connect to the OpenVPN Client container. It's not like you can't add a secondary VPN Client Cloudron app and connect it to another app if you really need more than one VPN connection, ya know?

                                                                                                                      Since that's how I'll be coding it, as soon as someone tells me how to use the app object in box to "get" the cloudron manifest ID. 😂 I'm assuming only girish or nebulon know that off the top of their head though so I'll have to reverse engineer that as soon as I figure out how to get the app passed this reverse nginx configuration barrier (which from the code looks like it's reading hostPort as null which is why no apps are working). It would be nice in that situation to know the function to get the hostPort of another container based on manifest id (my OpenVPN Client app to be exact). But once I RE those last two functions, I can do this.

                                                                                                                      1 Reply Last reply Reply Quote 0
                                                                                                                      • Lonkle
                                                                                                                        Lonkle last edited by Lonkle

                                                                                                                        Maybe these functions exist, maybe they don't. REing is hard. 😂 I've never really coded in Node (or used Docker) before this month so these are all new concepts to me.

                                                                                                                        1 Reply Last reply Reply Quote 0
                                                                                                                        • Lonkle
                                                                                                                          Lonkle last edited by Lonkle

                                                                                                                          Oh, I think the answer to my first question was really simple: app.manifest.id. 🤦‍♀️

                                                                                                                          Last thing is - I still need to find a way to get either container environment variables or the app object via only knowing the the cloudron manifest id. Then this should work perfectly.

                                                                                                                          1 Reply Last reply Reply Quote 0
                                                                                                                          • Lonkle
                                                                                                                            Lonkle last edited by

                                                                                                                            I mean, actually that would create a possible more than one object returned scenario.

                                                                                                                            That's fine though, I'll just take the first app of that mainfest id (since more than one Cloudron app with the same manifest id can be installed simultaneously).

                                                                                                                            1 Reply Last reply Reply Quote 0
                                                                                                                            • First post
                                                                                                                              Last post
                                                                                                                            Powered by NodeBB