A remote team accumulates public URLs: the database admin panel, the staging site, the monitoring dashboard, the CI server, each protected by a password and, hopefully, an IP allowlist that broke when someone moved house. The fix is old and unglamorous: put the team on a VPN, and take everything else off the internet. This post follows a DevOps engineer doing that on MassiveGRID PaaS, which is built on Virtuozzo Application Platform, formerly Jelastic, with the OpenVPN Access Server package.

The company is a 40-person fully remote analytics start-up we will call Quillon Data, with a dozen environments on one PaaS account: production, staging, a data warehouse, Jenkins, Grafana and several databases. The OpenVPN Access Server package deploys the server on a dedicated Linux node with a public IP, a web admin console and a client portal that hands each user a pre-configured profile.

The inventory of exposure

The engineer started with a list, and it was worse than expected: nine public hostnames for things no customer should reach. phpMyAdmin on two database environments. Grafana. Jenkins. Three staging sites. A Postgres port mapped through an endpoint that someone had opened for a migration and never closed. The container firewall on each was set to allow the team's home IPs, a list that had 60 entries for 40 people. The goal was zero public hostnames for internal tools, one public hostname for the VPN.

How the VPN server sits inside the account

The Access Server node has a public IP in the London region, the only public address the internal tools will have. It also sits on the account's internal network, like every other environment. In the admin console the engineer adds routes for the private address ranges of the environments the team needs, so a connected client reaches them over the tunnel by their internal addresses, while the client's ordinary internet traffic stays local (split tunnelling), which keeps video calls off the VPN. Each internal environment's container firewall is then changed to allow only the VPN server's internal address, and the public hostnames and endpoints are removed.

ResourceBeforeAfter
phpMyAdmin, pgAdminPublic hostname, password, IP allowlistInternal address via VPN; firewall allows VPN node only
Grafana, JenkinsPublic hostname, passwordInternal address via VPN
Staging sitesPublic hostname, basic authInternal address via VPN, or public with the shared balancer only when a client must review
Postgres 5432 endpointOpen since a migrationRemoved; direct internal access over VPN
Production sitePublic, as it should beUnchanged

Users, profiles and a second factor

Access Server's client portal is the reason the rollout took a day rather than a month. Each user logs into the portal, downloads OpenVPN Connect for their laptop or phone, and downloads a profile already configured for the server; there is nothing to type. The engineer connects Access Server's authentication to the company's identity provider so accounts follow the HR system, enables multi-factor authentication with time-based codes, and creates two groups: engineering, with routes to everything, and analysts, with routes to the warehouse and Grafana only. Leaving the company means disabling one account, not editing nine firewalls.

Licensing, stated plainly

OpenVPN Access Server is proprietary software from OpenVPN Inc. It is free for two concurrent connections, which is enough to evaluate everything above. Beyond that, concurrent connections are licensed by subscription from OpenVPN Inc., and the activation key is entered in the admin console. Quillon's engineer sized the subscription at 25 concurrent connections, since not all 40 people are connected at once, and Access Server reports peak usage so the number can be adjusted. The PaaS side is the node's resource use; the licence is a separate line paid to the vendor.

Sizing and cost of the server itself

OpenVPN's encryption is CPU work in proportion to throughput, and a team browsing admin panels and running database queries moves little data. The node idles at 2 to 3 cloudlets (a cloudlet is 128 MiB of RAM plus 400 MHz of CPU) and rises to 8 when analysts pull large query results, with vertical scaling allocating it by the hour. Averaged, about 4 cloudlets an hour, roughly $10 a month before discounts at MassiveGRID's published $0.003372 per cloudlet-hour, plus the public IP's hourly charge. The engineer's note to the CTO: the VPN server costs less than the coffee for the meeting in which the exposure list was read aloud.

What else the tunnel made possible

Logging closed the loop for the security review. Access Server records each connection with user, time and assigned tunnel address, and the engineer forwards those logs to the company's log store, so a query on a database admin panel can be tied to a person. The container firewalls' rejected-connection counters, visible in the platform, confirmed within a week that nothing was still knocking on the old public doors.

Two things the team had not planned. Database clients on laptops now connect directly to the internal database addresses, so the engineers stopped using web database panels altogether and the two phpMyAdmin instances were uninstalled. And the fixed egress address of the VPN server let the company allowlist one IP at a third-party data provider that had refused to accept 40 changing home addresses. The nine public hostnames became one, and the firewall allowlists became a single entry each.

Frequently Asked Questions

Can the VPN reach environments in other MassiveGRID regions?

Environments in different regions are in different data centres and are reached by their public addresses, not a shared internal network. Run an Access Server node in each region you need, or allow the VPN server's public IP through the container firewalls of the environments in the other region.

Is WireGuard an option instead of OpenVPN?

Not through this package, which is OpenVPN Inc.'s Access Server with its admin console and client portal. WireGuard can be run on a platform Linux node yourself if you prefer it; you would then build the user management and profile distribution that Access Server provides.

How do contractors get temporary access?

Create an account in a group with routes only to what the contractor needs, set an expiry in your identity provider or disable the account at the end of the engagement, and the profile stops working. The client portal gives them the same one-click setup as staff.

One public address for everything internal

Deploy OpenVPN Access Server with a public IP on MassiveGRID PaaS, route it to your environments' internal addresses and close every other public door. Per cloudlet-hour, two free connections to evaluate. Free 14-day trial.

OpenVPN Access Server on MassiveGRID PaaS

Further Reading