Can we restrict access to apps behind the OpenVPN app?
-
To further protect the apps running on a publicly accessible cloudron, I wanted to restrict the requests that a particular of set of apps would respond to by their originating IP address. In particular, I wanted this to be the IP address of the OpenVPN app. The idea is that to access say webmail.<server>.com, I would first have to connect to vpn.<server>.com using my VPN client, and only then would the webmail.<server>.com be visible or accessible. This would prevent indexing services, or possible hackers from even searching for what apps are hosted on the cloudron server.
Many apps provide whitelists in their configuration, so to start with, I am okay with configuring this inside the app itself. However, to do that, I need to know what the originating IP address internally would be for requests coming from the OpenVPN app. The OpenVPN app IP address externally is the same as the server IP address, but internally, I see that traffic coming from 172...* as prefix. Is this configured in box? Can we set static IPs internally for OpenVPN?
-
Also, this might not just be limited to OpenVPN IPs. I have seen use-cases where services could be using other service APIs like for eg. in case of vault, and it would be nice to restrict access to traffic from OpenVPN, and it's other calling apps.
-
I think based on this, the Nginx reverse proxy can limit access to IPs or subnets as required. Being able to configure this in a persistent way should work. Is there a way to configure nginx persistently? I am guessing that my changes in /etc/nginx/conf/applications would probably not be persistent?
I believe docker by default puts all IPs in the 172.17 range, so we could limit app access on HTTP, or even tcp/udp to those IPs for apps we want to further protect. They should then be accessible by OpenVPN users.
-
@esawtooth Yes, this is definitely possible. You can do this already, here's a rough outline. The steps will differ a bit based on your networking setup but let's say you are trying to set this up on AWS/DO.
- First, setup an OpenVPN server. This can be a Cloudron installation with OpenVPN app. So, this is your
vpn.server.com
. - Next, setup Cloudron which will host your apps. This server will have an internal IP. For example, on AWS or DO, you would do this by having these two servers in a VPC of their own.
- Be sure to use a "programmatic" DNS backend i.e anything other than wildcard/manual. Doing so, will help us get DNS certs for a server with internal IPs since it will use DNS automation to get Lets Encrypt certificates.
- For this server, go to Networking view (if cloudron is already installed) OR the Advanced section during the initial domain setup. Setup the IP to be that of the internal interface - https://docs.cloudron.io/networking/#network-interface or equivalent.
That's it!
To outline the setup a bit more for clarity with examples:
- Let's say there is a VPC/private network with 192.16.1.0/8
- The vpn.server.com has two IPs. A public IP and internal IP (say 192.168.1.10).
- The app Cloudron has internal IP 192.168.1.20. The app Cloudron has been configured to use the internal IP. So, it will automate the DNS setup to use this IP. For example,
blog.server.com
will have DNS entry as 192.168.1.20. External users cannot access it because it's an internal IP. But we can still get valid Let's Encrypt certs because Cloudron will use acme2 protocol + dns automation to get certs which doesn't require access to the server. - Once connected to VPN, you can connect to 192.168.1.20 and thus
blog.server.com
will work.
Hope that makes sense
- First, setup an OpenVPN server. This can be a Cloudron installation with OpenVPN app. So, this is your
-
@robi The apps are installed on the internal server and thus can only use the internal IP. As for the DNS, by default, Cloudron will try to "detect" the public IP by calling the endpoint https://api.cloudron.io/api/v1/helper/public_ip. To "override" this, one has to explicitly set the internal IP address using https://docs.cloudron.io/networking/#network-interface
-
@robi DO recently addded VPC - https://www.digitalocean.com/products/vpc/ and on linode you can assign a droplet with just private IP https://www.linode.com/docs/guides/remote-access/#adding-private-ip-addresses . From what I can tell, linode is not a VPC so it probably requires a bit more iptables configuration to restrict access.
-
@girish That makes sense. I guess I was really thinking inside the "box" on this one! While this would work, and would definitely be secure, doing it this way results in the following two issues to my mind:
-
It would need an extra machine on a VPS/cloud provider, and hence increased cost for the machine (and the potential cloudron license). Also, I am running on Hetzner, so not sure if they support VPC. Still, I'll try to see what I can do here. Using a proxy server, should work even if I cannot manage a VPC, if I can tell the hidden cloudron to blacklist all other public IPs other than the public IP of the VPS. Do you think that'd work too?
-
I would not be able to control what apps I expose publicly unless I put the public apps on a gateway cloudron, and the private apps on the hidden cloudron. If I do not use two cloudrons, this method would disable public access to all the apps, if I understood everything correctly and I would not, for example, be able to make connections to imap.server.com directly from my mail client unless it was hosted on the gateway cloudron.
Generally it makes sense for me to want to expose apps like surfer, wordpress, email endpoints for IMAP/SMTP etc. to the public internet, while keeping my webmail app and the control pages for internal services like my jupyter notebook secure behind a VPN to reduce attack surface area. Also, even if I go with the two cloudron approach, I'd have to synchronize data between the two cloudrons which would have it's own set of issues.
It'll likely work, but would not be that clean IMO. What I was mentioning is kind of similar to #1, save that the VPN server is an app on the cloudron, and instead of whitelisting the external IP for the whole cloudron, I'd be whitelisting the internal IP of the VPN app for the individual apps I want to protect. Not sure how feasible it is, but I feel it would be nicer to be able to label an app as "Private" or "Internal" vs "Public", and let the application nginx config block access to it to all save internal apps (including openvpn).
-
-
@robi I am still reading through the linked thread. The idea to route traffic for an app through the VPN client is pretty cool! Still I believe from the first post that the incoming traffic to the app is not routed through the VPN client? My understanding is that the OpenVPN client would anonymise the traffic of an app, but I would still be able to login or hit its APIs from the open internet right?
-
@esawtooth Agree with your comments overall. Generally, the two machine setup makes sense for corporate-y setups. The VPN server can be a standalone server. I only suggested using Cloudron+OpenVPN for convenience. But you can always set it up using other means. For example, in DO, a 5 USD droplet is more than sufficient for OpenVPN. So, there's no separate Cloudron subscription to pay. (related: Cloudron+OpenVPN is free as well since it's free for 2 apps+mail server). Atleast for the bigger business that use Cloudron, they already have a VPN setup. So, the internal Cloudron+external LDAP is how they keep all the apps internal.
But I think your bigger point is to determine if we can make this work in a single server setup with some sort of public/internal/private setting. I think that it will be great (and very useful to many of the smaller businesses) if we can figure what needs to be done to make it work. Let me re-read your original idea.
Also, your understanding about @lonk's work is correct. That one is meant to anonymize traffic originating from apps and not an access control measure for inbound traffic.
-
The nginx approach is not complete because that only restricts http traffic. Apps like gitlab/gitea/gogs/adblock and many more will all use different ports.
Funnily enough, I think what might actually work is to put the app container in the same network as the VPN app. Which is the solution as anonymizing external traffic for an app! The only difference is for this use case, we put it in VPN Server and for the other one we put it in VPN Client. So, @robi was right all along that these are related.
-
@girish Thanks Girish! One great value-add to me of cloudron is the simple setup of multiple apps and services with efficient utilization of the server resources. I am more of a hobbyist and lean towards using cloudron to self-host a lot of my digital footprint. From that point of view, a single server setup appears to make sense to me if it is feasible.
I did not consider that limitation of the nginx approach and completely agree that it's not great to bake in. I'll read the referred thread in more detail
-
Hey guys, still alive over here. Busier than usual this time of year, but happy to help out if you guys need anything. I don't have time to read the whole thread but if anyone has any questions or needs the latest OpenVPN Client (Beta), let me know and I'll package something up for somebody with instructions for the hot fix using the semi-official hot fix tool.
I haven't posted in here in awhile because I need to update my hot fix for 6.0 and until I do that, it has to run on v5.6.3 so I've just been waiting to find time to update the hot fix. Though ideally @girish and I will make have a solid game plan as to how he wants the VPN Client integrated in Cloudron whether as an app itself or an app setting a file chooser to pick a .ovpn file to "connect" an app to (admittedly I think this gives users the most conveyance of the feature - it's up to @girish and @nebulon on that decision, but I'll go in either direction they want).
-