Deploying a Self-Hosted VPN on AWS Using Pritunl
Deploying a Self-Hosted VPN on AWS Using Pritunl

Deploying a Self-Hosted VPN on AWS Using Pritunl

Project Type: Cloud Infrastructure / Network Security Cloud Provider: AWS (EC2, N. Virginia — us-east-1) VPN Platform: Pritunl (Community Edition) + OpenVPN

This walkthrough documents the end-to-end process of building a private, self-hosted VPN on Amazon Web Services. Instead of relying on a commercial VPN provider, this project stands up a dedicated cloud server running the open-source Pritunl VPN management platform, which manages an OpenVPN server underneath. The result is a personally controlled VPN endpoint for encrypting traffic, masking the originating IP address, and securely accessing resources through a single cloud-hosted exit node.

Goals

  • Provision a cloud virtual machine on AWS EC2 to act as the VPN host
  • Install and configure Pritunl, MongoDB, and OpenVPN on Ubuntu 24.04 LTS
  • Create a VPN organization, user, and server through the Pritunl web console
  • Generate and distribute a client connection profile
  • Connect a desktop client to the VPN and verify the connection is live
  • Confirm outbound traffic is correctly routed through the AWS-hosted IP address

Architecture Summary

A single EC2 instance acts as both the Pritunl management server and the OpenVPN endpoint. The instance terminates VPN connections from a client machine, encrypts/decrypts traffic, and routes it out to the public internet using the EC2 instance’s Elastic IP. MongoDB runs locally on the same instance to store Pritunl’s configuration, user, and organization data.

ComponentDetail
Cloud ProviderAmazon Web Services (AWS)
Compute ServiceAmazon EC2
RegionUS East (N. Virginia) — us-east-1
Operating SystemUbuntu Server 24.04 LTS (HVM), 64-bit (x86)
Instance Typet3.micro
VPN SoftwarePritunl (Community Edition)
VPN ProtocolOpenVPN
DatabaseMongoDB 8.0 (local)
Storage1 x 8 GiB EBS (gp) volume
Client AppPritunl Desktop Client

Prerequisites

  • An active AWS account with permissions to launch EC2 instances and manage security groups
  • An SSH client (built-in Terminal on macOS/Linux, or PuTTY / Windows Terminal on Windows) — this walkthrough uses the AWS Console’s built-in EC2 Instance Connect browser terminal
  • A local machine to install the Pritunl desktop client on
  • Basic familiarity with the Linux command line

1. Launching the EC2 Instance

The VPN server begins life as a standard EC2 virtual machine, launched from the EC2 console using the Quick Start workflow.

Instance Configuration

  • Open the EC2 console and select Instances → Launch an instance
  • Under Name and tags, name the instance vpn
  • Under Application and OS Images, select the Ubuntu Quick Start tile using the Ubuntu Server 24.04 LTS (HVM), SSD Volume Type AMI for 64-bit (x86)
  • Under Instance type, select t3.micro — sufficient for a low-to-moderate traffic personal VPN and eligible for the AWS Free Tier
  • Create (or select) a key pair for SSH access
  • Create a new security group (rules covered below)
  • Leave storage at the default: 1 volume, 8 GiB
  • Review the Summary panel, then select Launch instance

Security Group (Firewall) Rules

TypeProtocolPort RangeSourcePurpose
SSHTCP22My IPAdminister the server
HTTPSTCP4430.0.0.0/0Pritunl web admin console
Custom UDPUDP10081 (or chosen port)0.0.0.0/0OpenVPN tunnel traffic

Security note: Restricting SSH access to “My IP” rather than 0.0.0.0/0 significantly reduces the attack surface. The OpenVPN UDP port must stay open to the internet so remote clients can establish tunnels from anywhere.

image

2. Connecting to the Instance via SSH

Once the instance is in the Running state, connect over SSH to install the software. This walkthrough uses the EC2 Instance Connect browser-based terminal (Instances → select instance → Connect).

  • EC2 Instance Connect opens a terminal session directly in the browser — no local SSH client setup required
  • The default username for the Ubuntu AMI is ubuntu
  • Alternatively, use the downloaded .pem private key with a local SSH client: ssh -i "key.pem" ubuntu@<public-dns>
image

3. Installing Pritunl, MongoDB, and OpenVPN

Pritunl provides a web-based management layer on top of OpenVPN and WireGuard, and requires MongoDB as its backing datastore. All three components are installed from their official APT repositories, following Pritunl’s official documentation for “Other Providers — Ubuntu 24.04.”

Adding the Repositories

sudo tee /etc/apt/sources.list.d/mongodb-org.list << EOF
deb [ signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] \
  https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/8.0 multiverse
EOF

sudo tee /etc/apt/sources.list.d/openvpn.list << EOF
deb [ signed-by=/usr/share/keyrings/openvpn-repo.gpg ] \
  https://build.openvpn.net/debian/openvpn/stable noble main
EOF

sudo tee /etc/apt/sources.list.d/pritunl.list << EOF
deb [ signed-by=/usr/share/keyrings/pritunl.gpg ] \
  https://repo.pritunl.com/stable/apt noble main
EOF

Importing GPG Keys and Installing Packages

sudo apt --assume-yes install gnupg

curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | \
  sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg --dearmor --yes
curl -fsSL https://swupdate.openvpn.net/repos/repo-public.gpg | \
  sudo gpg -o /usr/share/keyrings/openvpn-repo.gpg --dearmor --yes
curl -fsSL https://raw.githubusercontent.com/pritunl/pgp/master/pritunl_repo_pub.asc | \
  sudo gpg -o /usr/share/keyrings/pritunl.gpg --dearmor --yes

sudo apt update
sudo apt --assume-yes install pritunl openvpn mongodb-org wireguard wireguard-tools

sudo ufw disable

sudo systemctl start pritunl mongod
sudo systemctl enable pritunl mongod

Note: sudo ufw disable turns off Ubuntu’s local firewall because traffic filtering is already handled by the AWS Security Group. In a production deployment, ufw can instead be configured to mirror the security group rules for defense-in-depth.

image

4. Initial Pritunl Setup

Once installed and running, Pritunl exposes a web-based admin console on port 443 of the server’s public IP. The first-run setup links the web console to the local MongoDB database and creates the initial administrator account, after which the Dashboard becomes available, summarizing organizations, users, servers, and a log of recent admin actions.

image

5. Configuring the Organization, User, and Server

Pritunl organizes access using a three-tier model: Organizations group Users, and Servers are attached to Organizations to grant their users VPN access. This project uses a single organization for simplicity.

Creating the Organization and User

  • From the Users tab, use Add Organization to create a new organization (named pixelr in this project)
  • Use Add User to create a user within that organization (named rupam)
  • Each user is automatically issued a unique cryptographic identity used to authenticate and encrypt their VPN session

Creating the VPN Server

From the Servers tab, create a new server (named pixel_vpn). Pritunl auto-assigns a virtual network range for connected clients and a listening port for OpenVPN traffic.

SettingValue
Server Namepixel_vpn
ProtocolOpenVPN (UDP)
Port10081
Virtual Network10.157.172.0/22
WireGuard Network10.197.216.0/22
Multiple DevicesDisabled

Attaching the Organization and Configuring Routes

Attach the pixelr organization to the pixel_vpn server, granting its users (rupam) permission to connect. Routes determine which traffic is sent through the VPN tunnel once a client connects:

  • 0.0.0.0/0 — routes all internet traffic through the VPN (full tunnel mode)
  • 10.157.172.0/22 — the OpenVPN virtual client network
  • 10.197.216.0/22 — the WireGuard virtual client network
  • 8.8.8.8/32 — a dedicated route for the DNS server used by connected clients

image

6. Starting the VPN Server

With the organization, user, server, and routes configured, start the server from the Servers tab using Start Server. Pritunl launches the underlying OpenVPN process and begins listening for client connections on the configured UDP port.

  • Status changes from Offline to Online
  • The Server Output panel begins streaming live OpenVPN log output
  • Uptime, connected Users, and connected Devices counters become active

7. Generating and Downloading the Client Profile

Each Pritunl user needs a connection profile — a bundle of certificates, keys, and server details required to authenticate and establish a tunnel.

Downloading the Profile

From the Users tab, the download icon next to rupam generates and downloads a profile archive (.tar) containing the OpenVPN configuration for that user.

Temporary Profile Links

Pritunl can also generate temporary, expiring URLs to the same profile — useful for sharing with a device that lacks admin console access, or for the Pritunl mobile client. Each link expires automatically after 24 hours.

image
Link TypeFormatExpiry
.tar profile downloadhttps://<server-ip>/key/<token>.tar24 hours
.zip profile downloadhttps://<server-ip>/key/<token>.zip24 hours
View profile links pagehttps://<server-ip>/k/<token>24 hours
Pritunl Client deep linkpritunl://<server-ip>/ku/<token>24 hours

8. Installing the Pritunl Desktop Client

image

Install the Pritunl Client application on the local machine. Official installers and package-manager instructions are published for:

  • Linux: distribution-specific repository and package manager commands (Arch, Debian, Fedora, Ubuntu, AlmaLinux, Oracle Linux)
  • macOS: a signed .pkg installer
  • Windows: a signed .exe installer

9. Connecting to the VPN

  • Open the Pritunl Client, choose Import, and select the downloaded rupam profile
  • Select the imported pixel_vpn profile from the client’s list and click Connect
  • Enter username/password if prompted, and confirm the connection status turns green/active
image

10. Verifying the Connection

With the VPN connected, two checks confirm the tunnel is functioning: the public-facing IP address matches the AWS EC2 instance, and the server logs an authenticated client session

image

.

Server-Side Confirmation

The pixel_vpn server shows Online status with one connected user and one connected device. The live Server Output log confirms a TLS authentication handshake succeeded and that a Data Channel cipher of AES-128-GCM was negotiated, alongside a successful client-auth command and an active radius authentication thread.

image

Throughput Test

A speed test run while connected confirms the tunnel is functional and measures real-world throughput through the EC2 instance, correctly detecting the connection as originating from Amazon’s Ashburn, VA infrastructure.

image

Results Summary

MetricResult
VPN Server StatusOnline
Connected Users1 / 1
Connected Devices1
Public Egress IP54.205.56.180 (AWS / Amazon.com Inc.)
Detected LocationAshburn, Virginia, United States
Cipher NegotiatedAES-128-GCM
Download Speed128.55 Mbps
Upload Speed7.04 Mbps
Ping269 ms

Outcome: The deployment successfully routes a client device’s internet traffic through a self-hosted AWS EC2 instance via an encrypted OpenVPN tunnel. The connecting client’s apparent public IP, ISP, and geographic location all correctly resolve to the AWS instance rather than the client’s actual network, confirming the VPN works as intended.

Considerations and Next Steps

Hardening

  • Attach an Elastic IP so the public IP doesn’t change on stop/start or instance replacement
  • Re-enable and configure ufw on the instance to mirror the AWS Security Group rules as a second layer of defense
  • Restrict the Pritunl admin console (port 443) to a trusted IP range rather than 0.0.0.0/0
  • Enable two-factor authentication for Pritunl admin accounts
  • Replace the default self-signed certificate on the Pritunl web console with one from a trusted CA (e.g. via Let’s Encrypt)

Scaling and Cost

  • A t3.micro instance is sufficient for light personal use; higher concurrent user counts or throughput needs would warrant a larger instance type
  • Data transfer out of AWS is billed per GB beyond the Free Tier allowance — worth monitoring for VPNs used as a full-tunnel internet exit point
  • Pritunl’s Enterprise tier adds features like multi-factor authentication enforcement, more granular access control, and high-availability clustering for deployments growing beyond a single-server setup

Monitoring

  • AWS CloudWatch can be enabled on the instance to track CPU, network, and disk metrics over time
  • Pritunl’s built-in Logs tab provides an audit trail of administrative actions and authentication events

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *